单向一对多关系的NHibernate配置 [英] NHibernate configuration for uni-directional one-to-many relation
问题描述
我正在尝试建立如下关系.每个主项目都有一个或多个明细项目:
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 asinverse="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"
andnot-null
on<key>
, NH3 and above will perform only two inserts insead of insert-insert-update.
这篇关于单向一对多关系的NHibernate配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!