我有一个非常简单的ClassMap
public class ContentMap : ClassMap<Content>
{
public ContentMap()
{
// Basic property mapping
// Parent property mapping
References(x => x.Category).Column("CategoryId");
}
}
使用它,我的映射完全正常,Category
属性不为空。
如果我尝试在第一个参考
下添加此行References(x => x.LastActive).Column("LastActiveSubCategoryId");
我的映射出错了。
如果LastActiveSubCategoryId
为空,Category
映射正常。如果它不为空,则将设置LastActiveSubCategoryId
,但CategoryId
为空。
实际属性本身很简单
public virtual Category Category { get; set; }
public virtual SubCategory LastActive { get; set; }
Category
或SubCategory
映射中也没有任何复杂的内容。它们看起来非常类似于ContentMap
类(只有一条参考线)
知道会导致这种行为的原因是什么?我只能使用一个参考文献吗?
更新
我看过SQL,这似乎正在发生,希望有人可以帮我理解原因。
使用Content
和CategoryId
null将LastActiveSubCategoryId
实体插入到数据库中。
插入Category
实体,然后更新语句更新Content
,仅更新CategoryId
字段而不更新。
如果没有SubCategory
,此时一切都会好的。
如果有SubCategory
,则稍后插入一些语句,然后更新Category
。在update语句中,正在修改一些不同的值(一些不需要因为插入后没有更改),包括CategoryId
和SubCategoryId
。除了现在CategoryId
为空,LastActiveSubCategoryId
不是。
那么为什么CategoryId
在更新时为空?
更新2
我用来实际插入对象的代码仅用于此时的一些基本测试。这些是相关的代码:
Category category = new Category();
dao.Save(category);
Content content = new Content();
category.AddContent(content); // Adds it to a list, like in the tutorial mBotros posted
dao.Save(Content);
SubCategory subCategory = new SubCategory();
content.AddSubCategory(subCategory);
dao.Save(subCategory);
// On the Content class
public virtual void AddSubCategory(SubCategory subCategory)
{
SubCategories.Add(subCategory);
LastActive = subCategory;
}
答案 0 :(得分:1)
数据库模式中存在循环引用,这会使插入行变得棘手
Content
引用SubCategory
和SubCategory
引用Content
。如果您尝试使用普通旧SQL插入行,则不能够执行此操作:
/* this line does not work because SubCategory 2 does not exist yet */
insert into Content (Id, LastActiveSubCategoryId) values (1, 2);
insert into SubCategory (Id, ContentId) values (2, 1);
你必须做这样的事情:
insert into Content (Id, LastActiveSubCategoryId) values (1, null);
insert into SubCategory (Id, ContentId) values (2, 1);
update Content set LastActiveSubCategoryId = 2 where Id = 1;
当您持久化NHibernate实体时,需要牢记这一点。修改AddSubCategory
以不设置LastActive
。首先保存两个实体,然后关闭循环。
// ... code to save Category and Content, then...
SubCategory subCategory = new SubCategory();
content.AddSubCategory(subCategory); // modified to *not* set LastActive
dao.Save(subCategory);
content.LastActive = subCategory;
dao.Update(content);
答案 1 :(得分:0)
您提到的LastActiveId
不在您展示的代码中。
您是否偶然尝试将列映射为参考和标量属性?
更新:您的代码段仍然不完整,或者您错过了将导致更新发生的事务/刷新。此外,您是否同时拥有一个名为SubCategories 的集合(未显示)和一个名为LastActive的属性?