单向一对多关系的NHibernate配置 [英] NHibernate configuration for uni-directional one-to-many relation

查看:16
本文介绍了单向一对多关系的NHibernate配置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试建立如下关系.每个项目都有一个或多个明细项目:

I'm trying to set up a relationship as follows. Each Master item has one or more Detail items:

public class Detail {
    public virtual Guid DetailId { get; set; }
    public virtual string Name { get; set; }
}
public class Master {
    public virtual Guid MasterId { get; set; }
    public virtual string Name { get; set; }
    public virtual IList<Detail> Details { get; set; }
}

和映射:

public class MasterMap : ClassMap<Master> 
{
    public MasterMap() 
    {
        Id(x => x.MasterId);
        Map(x => x.Name);
        HasMany(x => x.Details).Not.KeyNullable.Cascade.All();
    }
}
public class DetailMap : ClassMap<Detail> 
{
    public DetailMap() 
    {
        Id(x => x.Id);
        Map(x => x.Name);
    }
}

数据库表是:

masterId   uniqueidentifier NOT NULL
name       nvarchar(max) NULL

细节是:

DetailId   uniqueidentifier NOT NULL
name       nvarchar(max) NULL
MasterId   uniqueidentifier NULL
foreign key (masterId) references [Master]

我真的不关心从 Detail 返回到 Master 的链接——换句话说,Detail 对象本身对我的域层来说并不有趣.它们将总是通过它们的 Master 对象访问.

I don't really care to have a link from Detail back to Master -- in otherwords, Detail objects on their own are just not interesting to my domain layer. They will always be accessed via their Master object.

使用这样的代码:

Master mast = new Master 
{
    MasterId = new Guid(),
    Name = "test",
    Details = new List<Detail> 
    {
        new Detail { .DetailId = new Guid(), .Name = "Test1" },
        new Detail { .DetailId = new Guid(), .Name = "Test1" }
    }
};

using (transaction == Session.BeginTransaction) 
{
    Session.Save(mast);
    transaction.Commit();
}

这很好用,除了这篇文章中概述的疯狂限制:NHibernate先做一个INSERT,然后把Detail.MasterId设为NULL,然后再做一个UPDATE,把它设置成真正的MasterId.

This works great, except for a crazy limitation outlined in this post: NHibernate does an INSERT and puts Detail.MasterId as NULL first, then does an UPDATE to set it to the real MasterId.

真的,我不想要 MasterId 为 NULL 的 Detail 条目,所以如果我将 MasterId 字段设置为 NOT NULL,则 INSERT to Detail 将失败,因为正如我所说 NHibernate 试图放入 MasterId = NULL.

Really, I don't want Detail entries with NULL MasterIds, so if I set the MasterId field to NOT NULL, the INSERT to Detail will fail, because as I said NHibernate is trying to put in MasterId = NULL.

我想我的问题归结为:

如何让上述代码示例与我现有的域模型一起使用(例如,不添加 Detail.Master 属性),并且数据库中的 Detail.MasterId 字段设置为 NOT NULL?

How can I get the above code sample to work with my existing domain model (eg, without adding a Detail.Master property), and the Detail.MasterId field in the database set to NOT NULL?

有没有办法让 Nhibernate 在初始 INSERT 中放置正确的 MasterId,而不是在之后运行 UPDATE?这个设计决定有什么理由吗?-- 我正在努力理解为什么会这样.

Is there a way to get Nhibernate to just put the correct MasterId in the initial INSERT, rather than running an UPDATE afterwards? Is there rationale somewhere for this design decision? -- I'm struggling to see why it would be done this way.

推荐答案

你不能.引用我的回答中的链接您链接到的另一个问题:

You can't. To quote the link from my answer on the other question you linked to:

非常重要的注意事项:如果 关联的 列被声明为 NOT NULL, NHibernate 在创建或更新关联时可能会导致违反约束.为了防止这个问题,你必须使用标记为 inverse="true" 的多值端(集合或包)的双向关联.请参阅本章后面对双向关联的讨论.

Very Important Note: If the <key> column of a <one-to-many> association is declared NOT NULL, NHibernate may cause constraint violations when it creates or updates the association. To prevent this problem, you must use a bidirectional association with the many valued end (the set or bag) marked as inverse="true". See the discussion of bidirectional associations later in this chapter.

正如 Hazzik 正确指出的那样,这在 NHibernate 3 及更高版本中发生了变化.遗憾的是,文档尚未更新,所以这里是 Hazzik:

as Hazzik has rightly pointed out, this has changed in NHibernate 3 and above. The docs sadly haven't been updated, so here's Hazzik:

[如果你]在上设置inverse="false"not-null,NH3及以上只会执行在插入-插入-更新之后的两个插入.

[If you] set inverse="false" and not-null on <key>, NH3 and above will perform only two inserts insead of insert-insert-update.

这篇关于单向一对多关系的NHibernate配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆