Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对象与使用NHibernate和fluent保存子记录的目标类型不匹配_C#_Nhibernate_One To Many_Fluent - Fatal编程技术网

C# 对象与使用NHibernate和fluent保存子记录的目标类型不匹配

C# 对象与使用NHibernate和fluent保存子记录的目标类型不匹配,c#,nhibernate,one-to-many,fluent,C#,Nhibernate,One To Many,Fluent,我有两个班 联系方式 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 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;
    }
}
但是,当我尝试用以下行保存地址时

Session.Save(Contact.PostalAddresses[0])

它失败了,出现以下异常

获取Cloud.BusinessObjects.Contacts.Contact.RecordId时发生异常

和一个内在的例外

对象与目标类型不匹配


我确信问题出在我映射联系人和地址之间关系的方式上——但我一辈子都看不出我做错了什么。提前有什么建议和感谢吗?

重点是,使用
的映射有很多
引用
是用于对象关系映射。PostLaddress正在引用联系人(而不是其RecordId-GUID)。联系人有很多地址

必须表示为

public class PostalAddress : IDisposable
{
  ...
  public virtual Contact OwnedBy { get; set; } // the reference
这应该是可行的,因为NHibernate将能够处理关系的两端(PostLaddress和Contact),就像处理对象一样

注意:这里我们还可以看到Fluent映射的优点。它确实用“英语”描述了映射是如何工作的。谁
引用什么,谁
有很多关系

请尝试在这里阅读更多

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

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

}
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