为什么添加这一行搞砸了我的NHibernate映射?

时间:2011-04-23 02:57:31

标签: c# nhibernate

我有一个非常简单的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; }

CategorySubCategory映射中也没有任何复杂的内容。它们看起来非常类似于ContentMap类(只有一条参考线)

知道会导致这种行为的原因是什么?我只能使用一个参考文献吗?

更新

我看过SQL,这似乎正在发生,希望有人可以帮我理解原因。

使用ContentCategoryId null将LastActiveSubCategoryId实体插入到数据库中。

插入Category实体,然后更新语句更新Content,仅更新CategoryId字段而不更新。

如果没有SubCategory,此时一切都会好的。

如果有SubCategory,则稍后插入一些语句,然后更新Category。在update语句中,正在修改一些不同的值(一些不需要因为插入后没有更改),包括CategoryIdSubCategoryId。除了现在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;
}

2 个答案:

答案 0 :(得分:1)

数据库模式中存在循环引用,这会使插入行变得棘手 Content引用SubCategorySubCategory引用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的属性?