流畅的NHibernate和具有单列名称的复合ID

Dyl*_*lan 4 nhibernate fluent-nhibernate

我已经在FNH谷歌集团中发布了这个帖子,但这里是独家新闻:

我在遗留数据库中有一个具有复合ID的表.好吧,PK是暗示的,因为表实际上没有定义PK,但自然PK是WORKORDERID和IMAGEPATH列的组合:

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]
Run Code Online (Sandbox Code Playgroud)

我定义了这个类映射:

   /// <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();
       }
   }
Run Code Online (Sandbox Code Playgroud)

对于这堂课:

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 });
   }
}
Run Code Online (Sandbox Code Playgroud)

现在我知道我应该在References行的类图中定义WORKORDERID列.排除它后,我得到预期的错误:

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'.
Run Code Online (Sandbox Code Playgroud)

但是,当我包含它时,我得到Fluent NHibernate试图将WORKORDERID列添加到查询两次:

System.IndexOutOfRangeException: Invalid index 5 for this SqlParameterCollection with Count=5.
Run Code Online (Sandbox Code Playgroud)

我一直在尝试我能想到的每一个组合都无济于事.我正在用这段代码测试映射:

       [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();
           }
       }
Run Code Online (Sandbox Code Playgroud)

任何帮助赞赏.

Dyl*_*lan 6

弄清楚了.您不需要为父项添加引用属性.请注意调整后的映射中缺少多对一的情况:

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();
}
Run Code Online (Sandbox Code Playgroud)

这会产生以下HBM映射文件.修复方法是使composite-id具有指向父类的键多对一行.现在我可以坚持我的Attachment类.

<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>
Run Code Online (Sandbox Code Playgroud)