2013-05-25 66 views
0

我有兩個類;對象不符合保存NHibernate和流利的子記錄的目標類型

聯繫

public class Contact : IDisposable 
{ 
    private String email; 
    private String name; 
    private String address; 
    private Guid recordId; 

    public virtual String Id { get; set; } 
    public virtual String Forename { get; set; } 
    public virtual String Surname { get; set; } 
    public virtual String PictureUrl { get; set; } 
    public virtual String HomeNumber { get; set; } 
    public virtual String MobileNumber { get; set; } 


    public virtual DateTime LastUpdated { get; set; } 
    public virtual Byte[] Picture { get; set; } 

    [XmlIgnore] 
    public virtual IList<PostalAddress> PostalAddresses { get; set; } 
    public virtual String Address 
    { 
     get 
     { 
      return address; 
     } 

     set 
     { 
      address = value; 
      if (PostalAddresses == null) PostalAddresses = new List<PostalAddress>(); 

      if (!String.IsNullOrEmpty(address)) 
      { 
       PostalAddress postalAddress = new PostalAddress(Address) { OwnedBy = RecordId }; 

       PostalAddresses.Add(postalAddress); 
      } 


     } 
    } 

    public virtual String Email { 
     get 
     { 
      return email; ; 
     } 
     set 
     { 
      if (String.IsNullOrEmpty(name)) 
       ExtractName(value); 

      email = value; 
     } 
    } 

    public virtual String Name 
    { 
     get 
     { 
      return name; 
     } 

     set 
     { 
      // if name is actually an email address extract the name part and use that. 
      if (value.Contains('@')) 
       ExtractName(value); 
      else 
      { 
       // if name is just some text then use the first word as forename and the rest 
       // for a surname 
       name = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(value); 
       if (name.Contains(' ') && String.IsNullOrEmpty(Forename) && String.IsNullOrEmpty(Surname)) 
       { 
        String[] splitName = name.Split(' '); 

        Forename = splitName[0].Trim(); 
        Surname = name.Substring(Forename.Length).Trim(); ; 

       } 
       else 
       { 
        if (String.IsNullOrEmpty(Forename)) Forename = name; 
       } 



      } 

     } 
    } 

    private void ExtractName (String email) 
    { 
    } 
    /// <summary> 
    /// Extract numbers from what would be the name 
    /// </summary> 
    /// <param name="oldString"></param> 
    /// <returns></returns> 
    private String ExtractNumber (String oldString) 
    { 
    } 

    /// <summary> 
    /// Extract the forename and surname from an email - replacing .-_ with spaces 
    /// </summary> 
    /// <param name="newEmail"></param> 
    /// <param name="SplitChar"></param> 
    private void ExtractNameFromEmail(String newEmail,Char SplitChar) 
    { 
    } 

    public virtual Guid Owner { get; set; } 

    public virtual Guid RecordId 
    { 
     get 
     { 
      return recordId; 
     } 

     set 
     { 
      recordId = value; 
     } 
    } 

    public Contact() 
    { 
     RecordId  = Guid.NewGuid(); 
     Name   = String.Empty; 
     Email   = String.Empty; 
     Forename  = String.Empty; 
     Surname   = String.Empty; 
     Address   = String.Empty; 
     PictureUrl  = String.Empty; 
     PostalAddresses = new List<PostalAddress>(); 
    } 

    public void Dispose() 
    { 
     Name  = String.Empty; 
     Email  = String.Empty; 
     Forename = String.Empty; 
     Surname = String.Empty; 
     Address = String.Empty; 
     PictureUrl = String.Empty; 
     PostalAddresses = null; 
    } 
} 

的PostalAddress

public class PostalAddress : IDisposable 
    { 

     public PostalAddress() 
     { 
      RecordId = Guid.NewGuid(); 
      AddressType = PostalAddressType.HOME; 
      Address = String.Empty; 
      Town = String.Empty; 
      County = String.Empty; 
      Postcode = String.Empty; 
      Country = String.Empty; 
     } 

     public virtual Guid RecordId { get; set; } 

     /// <summary> 
     /// Format the address stored in a String 
     /// </summary> 
     /// <param name="Address"></param> 
     public PostalAddress(String AddressText) 
     { 
     } 

     /// <summary> 
     /// Type of address 
     /// </summary> 
     public virtual PostalAddressType AddressType { get; set; } 

     /// <summary> 
     /// Text part of Address 
     /// </summary> 
     public virtual String Address { get; set; } 

     /// <summary> 
     /// Locality 
     /// </summary> 
     public virtual String Locality { get; set; } 
     /// <summary> 
     /// Town 
     /// </summary> 
     public virtual String Town { get; set; } 


     /// <summary> 
     /// County 
     /// </summary> 
     public virtual String County { get; set; } 

     /// <summary> 
     /// Post or Zip code 
     /// </summary> 
     public virtual String Postcode { get; set; } 

     /// <summary> 
     /// Country 
     /// </summary> 
     public virtual String Country { get; set; } 

     public virtual Guid OwnedBy { get; set; } 

     public void Dispose() 
     { 
      AddressType = PostalAddressType.HOME; 
      Address = String.Empty; 
      Town = String.Empty; 
      County = String.Empty; 
      Postcode = String.Empty; 
      Country = String.Empty; 
     } 
    } 

而對於兩類

映射ContactMap

public class ContactMap : ClassMap<Contact> 
    { 
     public ContactMap() 
     { 
      Table("Contacts"); 
      Id(x => x.RecordId); 
      HasMany<PostalAddress>(x => x.PostalAddresses) 
       .KeyColumns.Add("RecordId", mapping => mapping.Name("RecordId")); 
      Map(x => x.Id); 
      Map(x => x.Email); 
      Map(x => x.Forename); 
      Map(x => x.HomeNumber); 
      Map(x => x.LastUpdated); 
      Map(x => x.MobileNumber); 
      Map(x => x.Owner); 
      Map(x => x.Picture); 
      Map(x => x.PictureUrl); 
      Map(x => x.Surname); 

     } 
    } 

AddressMap

public class AddressMap : ClassMap<PostalAddress> 
{ 
    public AddressMap() 
    { 
     Table("PostalAddresses"); 
     Id(x => x.RecordId).GeneratedBy.Assigned(); 
     Map(x => x.AddressType); 
     Map(x => x.Address).Column("AddressText"); 
     Map(x => x.Locality); 
     Map(x => x.Town); 
     Map(x => x.County); 
     Map(x => x.Country); 
     Map(x => x.Postcode); 
     References(x => x.OwnedBy) 
      .Class<Contact>().Columns("OwnedBy"); 

    } 
} 

後續代碼用於保存的聯繫人。

public void Insert (Contact Contact) 
{ 
    ISessionFactory factory = null; 
    ITransaction transaction = null; 

    try 
    { 
     if (Contact.RecordId == null) Contact.RecordId = Guid.NewGuid(); 

     factory = CreateSessionFactory(); 
     using (var session = factory.OpenSession()) 
     { 
      transaction = session.BeginTransaction(); 

      if (Contact.PostalAddresses.Count > 0) 
       session.Save(Contact.PostalAddresses[0]); 
      session.Save(Contact); 
      transaction.Commit(); 
     } 
    } 
    catch (System.Exception ex) 
    { 
     throw ex; 
    } 

} 

然而,當我嘗試並保存地址與以下行

Session.Save(Contact.PostalAddresses[0]);

它失敗,出現以下異常發生

異常Cloud.BusinessObjects.Contacts的吸.Contact.RecordId

而且

對象的內部異常不匹配目標類型。

我相信這個問題是在我映射一個聯繫人和地址之間的關係的方式 - 但我的生活不能看到我在做什麼錯。任何建議和提前感謝?

回答

1

重點是,與HasManyReferences映射的是對象關係映射。 的PostalAddress被引用聯繫(而不是它的recordId - GUID)。而聯繫有很多地址

public class PostalAddress : IDisposable 
{ 
    ... 
    public virtual Guid OwnedBy { get; set; } // this is not a Reference 

必須表示爲

public class PostalAddress : IDisposable 
{ 
    ... 
    public virtual Contact OwnedBy { get; set; } // the reference 

這應該工作,因爲NHibernate的將是能夠與關係的兩端(的PostalAddress和聯繫方式)的工作使用對象

注:這裏我們也可以看到流利的映射advanatage。它確實在「英文」中描述了映射的工作原理。誰references什麼,誰has many關係

請儘量讀到這裏http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-manytoone更多...