【问题标题】:Fluent NHibernate mapping failing when saving child objects保存子对象时流利的 NHibernate 映射失败
【发布时间】:2015-11-22 07:11:41
【问题描述】:

我确实尝试使用这个问题Setting up one to many relationship with Fluent Nhibernate 作为基础,但仍然有问题。

我有两个类 - Contact 和 PostalAddress - 一个联系人可以有多个地址。问题是当它使用 PostalAddress 到达一个类时,它会失败并显示

此 SqlParameterCollection 的索引 1 无效,Count=1。

针对该特定联系人有一个地址

联系班级

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace YourLivesDataEngine.DataObjects
{
    [DataContract()]
    public class Contact
    {
        private String givenName;
        private String surname;
        private String middleName;
        public Contact()
        {
            Emails              = new List<EmailAddress>();
            Addresses           = new List<PostalAddress>();
            TelephoneNumbers    = new List<TelephoneNumber>();

            givenName           = String.Empty;
            surname             = String.Empty;
            middleName          = String.Empty;

            Id                  = Guid.NewGuid().ToString();
        }
        [DataMember]
        public virtual String Id { get; set; }
        [DataMember]
        public virtual DateTime LastUpdated { get; set; }
        [DataMember]
        public virtual String Network { get; set; }
        [DataMember]
        public virtual String NetworkId { get; set; }
        [DataMember]
        public virtual String Name { get; set; }
        [DataMember]
        public virtual String GivenName { get; set; }
        [DataMember]
        public virtual String Surname { get; set; }
        [DataMember]
        public virtual String MiddleName { get; set; }
        [DataMember]
        public virtual IList<EmailAddress> Emails { get; set; }
        [DataMember(Name="Addresses")]
        public virtual IList<PostalAddress> Addresses { get; set; }
        [DataMember]
        public virtual IList<TelephoneNumber> TelephoneNumbers { get; set; }


    }
}

邮政地址类

public class PostalAddress
{
    public PostalAddress()
    {
        Id = Guid.NewGuid().ToString();
    }
    [DataMember]
    public virtual String Id { get; set; }
    public virtual String Address { get; set; }
    public virtual String Owner { get; set; }
    public virtual String AddressType { get; set; }
    public virtual Contact Contact { get; set; }
}

还有我的映射

联系人地图

public class ContactMap : ClassMap<Contact>
{
    public ContactMap()
    {
        Table("tblContacts");
        Id(x => x.Id);
        Map(x => x.LastUpdated);
        Map(x => x.Network);
        Map(x => x.NetworkId);
        Map(x => x.Name);
        Map(x => x.GivenName);
        Map(x => x.Surname);
        Map(x => x.MiddleName);

        HasMany<PostalAddress>(x => x.Addresses)
            .Inverse()
            .KeyColumns.Add("Id", mapping => mapping.Name("Id"))
            .Cascade.SaveUpdate()
    }
}

邮政地址地图

   public class PostalAddressMap 
        : ClassMap<PostalAddress>
    {
        public PostalAddressMap()
        {
            Table("tblPostalAddresses");
            Id(x => x.Id);
            Id(x => x.Address);
            Id(x => x.AddressType);
            Id(x => x.Owner);

            References(x => x.Contact)
                .Class<Contact>()
                .Column("Owner");

        }
    }

保存联系人的代码是

   public void Save ( Contact Contact )
    {
        try
        {
            using (ISessionFactory factory = CreateSessionFactory())
            {
                using (var session = factory.OpenSession())
                {
                    using (ITransaction transaction = session.BeginTransaction())
                    {
                        // save the contact
                        session.Save(Contact);
                        transaction.Commit();

                    }
                }
            }
        }
        catch ( System.Exception e)
        {
            throw e;
        }
        finally
        {

        }

    }

我确定这与设置映射的方式有关,但看不到它,虽然有些联系人没有地址 - 有些人有,所以我至少应该有一些地址。

【问题讨论】:

  • 您是否通过 PersistenceSpecification 测试器验证了您的地图?我附近没有 VS,所以语法可能会关闭:gist.github.com/mxmissile/d81682def1d88a522767
  • 否 - 我刚刚通过注释掉 PostalAddressMap 中引用所有者的行来消除问题中的错误。现在它没有将 Id 写入 PostalAddress 记录,因此无法将 Id 设置为 null - 这是不允许的,因为它是主键 - 因此不允许 null。
  • 首先,您的PostalAddressMap 是错误的,您将属性映射为 Id。
  • 但是我会改变什么来修复它 - 我不确定,只有在尝试关联两个类时才会遇到这个问题。
  • 抱歉 - 没有注意到我在应该使用“地图”的地方使用了 Id,但是已经改变了现在这个 SqlParameterCollection 的无效索引 4,Count=4。这恰好是 PostalAddress 中映射属性的数量 - 现在不确定我需要解决什么问题。 - 提前感谢

标签: c# nhibernate fluent-nhibernate


【解决方案1】:

在 mxmissile 的帮助下,现已修复它。

问题都在 PostalAddress 的映射中。首先,我已将所有字段设置为 ID,因此将所需属性更改为 Map。

然后,每次我尝试保存地址时,此 SqlParameterCollection 的 Invalid index 4 都会出现 Count=4 错误。当一个字段被映射两次时会导致此错误。对于这个映射,它是被映射两次的所有者。它不需要在地图中列出 - 通过将其注释掉应用程序有效。修改后的Mapping类如下;

public class PostalAddressMap 
    : ClassMap<PostalAddress>
{
    public PostalAddressMap()
    {
        Table("tblPostalAddresses");
        Id(x => x.Id);
        Map(x => x.Address);
        Map(x => x.AddressType);

        References(x => x.Contact)
            .Class<Contact>()
            .Column("Owner");

    }
}

完成这些更改后,应用程序会正确保存联系人和地址。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-26
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    • 2010-12-01
    相关资源
    最近更新 更多