Free NHibernate and Composite Identifier with One Column Name

I crossed this in the Google FNH group, but here's the scoop:

I have a table in an old database that has a composite identifier. Well, PK is implied, since the table does not actually have PK, but a natural PC is a combination of WORKORDERID and IMAGEPATH Columns:

CREATE TABLE [WORKORDERIMG]( [WORKORDERID] [varchar](50) NULL, [IMAGEPATH] [varchar](250) NULL, [WOTASKID] [numeric](10, 0) NULL, [ATTACHEDBY] [nvarchar](100) NULL, [COMMENTS] [nvarchar](256) NULL, [DATETIMEATTACHED] [datetime] NULL ) ON [PRIMARY] 

I defined this class:

  /// <summary> /// NHibernate mapping for workorder attachments /// </summary> public class AttachmentMap : ClassMap<Attachment> { public AttachmentMap() { SchemaIs(Resources.DatabaseSchema); WithTable(ObjectNames.TableWorkorderAttachment); UseCompositeId() .WithKeyProperty(x => x.ParentId, "WORKORDERID") .WithKeyProperty(x => x.FileLocation, "IMAGEPATH"); Map(x => x.AttachedByUser, "ATTACHEDBY").WithLengthOf(100).Nullable(); Map(x => x.AttachedOn, "DATETIMEATTACHED").Nullable(); Map(x => x.Comments).Nullable().WithLengthOf(256); References(x => x.ParentWorkorder).FetchType.Join(); } } 

For this class:

 public class Attachment { public virtual string ParentId { get; set; } public virtual string FileLocation { get; set; } public virtual Workorder ParentWorkorder { get; set; } public virtual string AttachedByUser { get; set; } public virtual string Comments { get; set; } public virtual DateTime? AttachedOn { get; set; } public override bool Equals(object obj) { return this.IsEqual(obj); } public override int GetHashCode() { return HashCodeGenerator.GenerateHashCode(new object[] { FileLocation, ParentId }); } } 

Now I know that I have to define the WORKORDERID column in classmap for the References line. Eliminating this, I get the expected error:

 NHibernate: INSERT INTO azteca.WorkOrderImg (ATTACHEDBY, DATETIMEATTACHED, Comments, ParentWorkorder_id, WORKORDERID, IMAGEPATH) VALUES (@p0, @p1, @p2, @p3, @p4, @p5);@p0 = 'SYSTEM', @p1 = 3/15/2009 12:00:00 AM, @p2 = 'Some comment', @p3 = NULL, @p4 = NULL, @p5 = 'some ile\location' System.Data.SqlClient.SqlException: Invalid column name 'ParentWorkorder_id'. 

However, when I turn it on, I get Fluent NHibernate trying to add WORKORDERID to the request twice:

 System.IndexOutOfRangeException: Invalid index 5 for this SqlParameterCollection with Count=5. 

I have tried every combination that I can think of to no avail. I'm testing the display with this code:

  [Test] public void Can_persist_an_attachment() { var sf = ObjectFactory.GetNamedInstance<ISessionFactory> (ObjectMother.Datasource); using (ISession session = sf.OpenSession()) { new PersistenceSpecification<Attachment>(session) .CheckProperty(x => x.AttachedByUser, "SYSTEM") .CheckProperty(x => x.AttachedOn, new DateTime(2009, 3, 15)) .CheckProperty(x => x.Comments, "Some comment") .CheckProperty(x => x.FileLocation, "some\file\\location") .VerifyTheMappings(); } } 

Any help was appreciated.

+4
source share
1 answer

Figured it out. You do not need to add a reference property for the parent. Note that the adjusted match is missing many-one:

 public AttachmentMap() { SchemaIs(Resources.CityworksDatabaseSchema); WithTable(ObjectNames.TableWorkorderAttachment); UseCompositeId() .WithKeyReference(x => x.ParentWorkorder, "WORKORDERID") .WithKeyProperty(x => x.FileLocation, "IMAGEPATH"); Map(x => x.AttachedByUser, "ATTACHEDBY").WithLengthOf(100).Nullable(); Map(x => x.AttachedOn, "DATETIMEATTACHED").Nullable(); Map(x => x.Comments).Nullable().WithLengthOf(256); //References(x => x.ParentWorkorder, "WORKORDERID").FetchType.Join(); } 

This results in the following HBM mapping file. The fix is ​​that the composite identifier has a key-to-many-to-one string that points to the parent class. Now I can save my Attachment class.

 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access=""> <class name="Woolpert.Cityworks.Core.Entities.Azteca.Attachment, Woolpert.Cityworks.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="WorkOrderImg" xmlns="urn:nhibernate-mapping-2.2" schema="azteca"> <composite-id> <key-many-to-one class="Woolpert.Cityworks.Core.Entities.Azteca.Workorder, Woolpert.Cityworks.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="ParentWorkorder" column="WORKORDERID" /> <key-property type="String" name="FileLocation" column="IMAGEPATH" /> </composite-id> <property name="AttachedByUser" type="String"> <column name="ATTACHEDBY" length="100" not-null="false" /> </property> <property name="AttachedOn" type="System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"> <column name="DATETIMEATTACHED" not-null="false" /> </property> <property name="Comments" type="String"> <column name="Comments" length="256" not-null="false" /> </property> </class> </hibernate-mapping> 
+6
source

All Articles