【问题标题】:(Fluent) NHibernate: HasMany/References (bidirectional) + Cascade Save(Fluent) NHibernate: HasMany/References (双向) + Cascade Save
【发布时间】:2015-03-09 16:08:50
【问题描述】:

X引用Y,Y有很多X的场景中,如何配置双向映射的映射,这样当我在Y实例中添加很多X,保存Y实例时,工作正常吗?

为了让问题更清楚,这里是代码:

ClientCompany 模型有HasMany ContactPerson 相关模型:

public class ClientCompany
{
    // .... 
    public virtual ISet<ContactPerson> ContactPeople { get; set; }
}

// mapping:
HasMany(x => x.ContactPeople)
            .AsSet()
            .Inverse()
            .Cascade.All();

ContactPerson 具有引用母公司的不可为空的“ClientCompany”字段:

public class ContactPerson
{
    // ....
    public virtual ClientCompany ClientCompany { get; set; }
}

References(x => x.ClientCompany).Not.Nullable();

调用此代码:

sess.Save(new ClientCompany()
            {                    
                ContactPeople = new HashSet<ContactPerson>()
                {
                    new ContactPerson()
                }
            });

导致此异常:

非空属性引用空值或瞬态值 xxxx.ContactPerson.ClientCompany

这只是简化的情况,我在实际项目中使用 AutoMapper,所以手动设置参考 不是解决方案

【问题讨论】:

    标签: c# nhibernate fluent-nhibernate


    【解决方案1】:

    ORM 世界中最重要的思想,即在使用 NHibernate 时,是:

    总是设置关系的双方

    这是有效的方式,如何设置两边:

    var person = new ContactPerson();
    var company = new ClientCompany
    {                    
        ContactPeople = new HashSet<ContactPerson>()
        {
            person,
        },
    };
    person.ClientCompany = company
    
    sess.Save(company);
    

    通过映射是声明为负责其关系的Person(逆映射.Inverse())。

    这意味着,它必须已经设置了与其父级的关系。此关系稍后用于 INSERT 语句...并且不能为空。

    无需单独保存公司和人员。 唯一必要的绝对重要的是设置两个参考边。这是必须的。

    不确定您可以使用自动映射器做什么...但是双向设置的某种包装/屏蔽可能是 POCO 对象上的一些特殊方法:

    public class ClientCompany
    {
        // .... 
        public virtual ISet<ContactPerson> ContactPeople { get; set; }
        public virtual AddPerson(ContactPerson person)
        {
            ContactPeople = ContactPeople ?? new HashSet<ContactPerson>();
            ContactPeople.Add(person);
            person.ClientCompany = this;
        }
    }
    

    现在我们只需要在合适的时间致电AddPerson()...

    【讨论】:

    • 谢谢!我想我可以在“公司”对象上调用“保存”时以某种方式让它“自动”设置引用。这样就可以让 AutoMapper 发挥作用。
    • 必须明确设置引用。这真的很关键。如果你这样做,其余的将由 NHibernate 处理......另一种方法去 (但我不确定你的自动映射器能够做什么) 是创建特殊方法 @987654326 @ 并在那里实现双向设置 (parent-to-child, child-to-parent) ... 但是 AutoMapper 必须能够调用这样的方法 AddPerson()
    猜你喜欢
    • 2011-04-15
    • 2011-02-27
    • 2012-07-26
    • 2012-04-03
    • 1970-01-01
    • 2012-10-19
    • 2010-11-25
    • 2011-12-20
    • 1970-01-01
    相关资源
    最近更新 更多