2009-10-17 9 views
4

j'ai croisé a publié ce billet dans le groupe HNF Google, mais voici le scoop:Courant NHibernate et ID composite avec nom de colonne

J'ai une table dans une base de données existante qui a un ID composite. Eh bien, la PK est implicite puisque la table n'a pas en fait un PK défini, mais le PK naturel est la combinaison des colonnes WORKORDERID et 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] 

Je cette carte de classe définie:

/// <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(); 
     } 
    } 

Pour cette classe:

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 }); 
    } 
} 

maintenant, je sais que je devrais être en train de définir la colonne WORKORDERID en t Il a également créé la classe pour la ligne Références. Avec elle exclu que je reçois la erreur attendue:

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'. 

Cependant, quand je l'inclus je reçois Fluent NHibernate essayer d'ajouter la colonne de WORKORDERID à la requête deux fois:

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

Je suis essayant chaque combinaison que je peux penser en vain. Je tester la mise en correspondance avec ce 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(); 
      } 
     } 

Toute aide appréciée.

Répondre

6

Compris. Vous n'avez pas besoin d'ajouter la propriété de référence pour le parent. Remarquez comment many-to-one manque dans la mise en correspondance ajustée:

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(); 
} 

Il en résulte dans le fichier de mappage de HBM suivant. Le correctif consiste à avoir l'ID-composite avec une ligne key-many-to pointant vers la classe parente. Maintenant, je peux persister ma classe d'attachement.

<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> 
Questions connexes