I've been slowly replacing our NHibernate XML mapping files with ClassMap and ran into a minor snag with our composite key classes. Unfortunately we are supporting a legacy database that uses some evil and nasty composite keys... I hate 'em but we can't change the schema. To solve this problem, I created the CompositeComponentId with the CompositeComponentPart class to support mapping composite-id to a class. The CompositeComponentId works similarly to Component:
CompositeComponentId<IdentityClass>(x => x.Property, m => { m.WithKeyProperty(x => x.Property, "FieldName"); m.WithKeyReference(x => x.Property, "FieldName"); }); Keep in mind this code is a sideline addition created by me and I do not guarantee it will meet your needs or that it will work for you. This is a temporarily solution I created to meet my immediate needs so feel free to use it at your own risk. I elected this approach because it minimizes the changes to the existing code base (e.g. adds one method to ClassMapBase and adds one class to the Mapping folder). All that's needed it to add CompositeComponentId to ClassMapBase: public virtual CompositeComponentPart<C> CompositeComponentId<C> (Expression<Func<T, object>> expression, Action<CompositeComponentPart<C>> action) { PropertyInfo property = ReflectionHelper.GetProperty(expression); CompositeComponentPart<C> part = new CompositeComponentPart<C> (property); AddPart(part); action(part); return part; } and add the CompositeComponentPart class: using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Reflection; using System.Xml; namespace FluentNHibernate.Mapping { public class CompositeComponentPart<T> : IMappingPart, IAccessStrategy<CompositeComponentPart<T>> { private readonly AccessStrategyBuilder<CompositeComponentPart<T>> _access; private readonly IList<KeyProperty> _keyProperties; private readonly PropertyInfo _property; public CompositeComponentPart(PropertyInfo property) { _property = property; _keyProperties = new List<KeyProperty>(); _access = new AccessStrategyBuilder<CompositeComponentPart<T>> (this); } public void SetAttribute(string name, string value) { throw new NotImplementedException(); } public void SetAttributes(Attributes atts) { foreach(var key in atts.Keys) { SetAttribute(key, atts[key]); } } public void Write(XmlElement classElement, IMappingVisitor visitor) { XmlElement element = classElement.AddElement("composite-id") .WithAtt("class", _property.PropertyType.FullName) .WithAtt("name", _property.Name); foreach(var keyProp in _keyProperties) { keyProp.Write(element, visitor); } } public int Level { get { return 1; } } public PartPosition Position { get { return PartPosition.First; } } /// <summary> /// Defines a property to be used as a key for this composite-id. /// </summary> /// <param name="expression">A member access lambda expression for the property</param> /// <returns>The composite identity part fluent interface</returns> public CompositeComponentPart<T> WithKeyProperty(Expression<Func<T, object>> expression) { return WithKeyProperty(expression, null); } /// <summary> /// Defines a property to be used as a key for this composite-id with an explicit column name. /// </summary> /// <param name="expression">A member access lambda expression for the property</param> /// <param name="columnName">The column name in the database to use for this key, or null to use the property name</param> /// <returns>The composite identity part fluent interface</returns> public CompositeComponentPart<T> WithKeyProperty(Expression<Func<T, object>> expression, string columnName) { var prop = ReflectionHelper.GetProperty(expression); var keyProperty = new KeyProperty(prop, false) { ColumnName = columnName }; _keyProperties.Add(keyProperty); return this; } /// <summary> /// Defines a reference to be used as a many-to-one key for this composite-id with an explicit column name. /// </summary> /// <param name="expression">A member access lambda expression for the property</param> /// <returns>The composite identity part fluent interface</returns> public CompositeComponentPart<T> WithKeyReference(Expression<Func<T, object>> expression) { return WithKeyReference(expression, null); } /// <summary> /// Defines a reference to be used as a many-to-one key for this composite-id with an explicit column name. /// </summary> /// <param name="expression">A member access lambda expression for the property</param> /// <param name="columnName">The column name in the database to use for this key, or null to use the property name</param> /// <returns>The composite identity part fluent interface</returns> public CompositeComponentPart<T> WithKeyReference(Expression<Func<T, object>> expression, string columnName) { var property = ReflectionHelper.GetProperty(expression); var keyProperty = new KeyProperty(property, true) { ColumnName = columnName }; _keyProperties.Add(keyProperty); return this; } /// <summary> /// Set the access and naming strategy for this identity. /// </summary> public AccessStrategyBuilder<CompositeComponentPart<T>> Access { get { return _access; } } } } --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Fluent NHibernate" group. To post to this group, send email to fluent-nhibernate@googlegroups.com To unsubscribe from this group, send email to fluent-nhibernate+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/fluent-nhibernate?hl=en -~----------~----~----~----~------~----~------~--~---