0

我有两节课;

接触

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

邮寄地址

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

以及这两个类的映射

联系方式图

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

}

但是,当我尝试使用以下行保存地址时

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

它失败了,但有以下异常

Cloud.BusinessObjects.Contacts.Contact.RecordId 发生异常

和一个内在的例外

对象与目标类型不匹配。

我确定问题出在我映射联系人和地址之间关系的方式上——但对于我的生活来说,我看不到我做错了什么。有什么建议和提前感谢吗?

4

1 回答 1

1

关键是,与HasManyandReferences的映射用于对象关系映射。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 和 Contact)的两端一起工作

注意:这里我们也可以看到 Fluent 映射的优势。它确实用“英语”描述了映射的工作原理。谁references什么,和谁的has many关系

请尝试在这里阅读http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-manytoone更多...

于 2013-05-26T04:33:28.957 回答