为什么我的类将一个集合保存到数据库,而不将另一个保存到数据库
本文关键字:数据库 保存 另一个 集合 一个 我的 为什么 | 更新日期: 2023-09-27 18:26:39
这让我抓狂。我可以在类上保存其中一个集合,但不能保存另一个。
我有一门课叫Category
public Category()
{
Items = new List<Item>();
Prices = new List<Price>();
}
这两种方法几乎完全相同。构造函数分别设置一个名为Category
的属性以及它们的Name
和Price
。
public virtual Item AddItem(string name)
{
var item = new Item(this, name);
Items.Add(item);
return item;
}
public virtual Price AddPrice(decimal price)
{
var price = new Price(this, price);
Prices.Add(price);
return price;
}
映射
public class CategoryMap : ClassMap<Category>
{
public CategoryMap()
{
// Other properties
HasMany(x=>x.Items).Cascade.AllDeleteOrphan();
HasMany(x=>x.Prices).Cascade.AllDeleteOrphan();
}
}
正如您所看到的,这两个集合的映射方式完全相同。
Price
和Item
的映射都具有相同的映射
References(x=>x.Category);
据我所知,这两个人几乎所有的东西都是一样的。有问题
category.AddItem(someName);
session.Save(category); // Works
category.AddPrice(somePrice);
session.Save(category); // Doesn't work
这些都在我用来填充测试数据库的文件中。保存项目效果良好。节省价格不会。类和映射是相同的。我想不通。
映射应该可以正常工作,因为直接调用构造函数可以正常工作
session.Save(new Price(category, 1));
那么,为什么Category保存一个集合而不保存另一个呢?我运行了profiler,该类甚至没有试图保存Price集合。
更新:
正如Gabe在评论中指出的那样,如果我交换调用,以便在Item之前调用Price,则Price会进入数据库,而Item不会。
如果我在每次更新集合后调用session.Flush()
,它会正常工作。我应该这样做吗,或者有没有办法修复我的映射使其工作?
尝试交换调用的顺序(先加价格,然后加项目),看看Price
映射是否真的有问题,或者问题是第二次调用失败。
关于flush
-大多数情况下,您不需要显式调用flush
,这是nHibernate在需要时会在后台执行的操作(此处详细信息)。刷新模式不是映射问题(它是一个会话属性,您可以设置,但通常不必设置)。
如果将代码封装在事务中,则不需要flush
。如果你不是,你应该是,这可能是你的问题。
using (var tx = Session.BeginTransaction()) {
category.AddItem(someName);
category.AddPrice(somePrice);
session.Save(category);
tx.Commit();
}
更新:我想我知道你的问题是什么。给定您的代码,看起来您正在创建一个新的category
对象并用数据填充它。在第一个Save()
上,nHibernate执行自动刷新,因为在从数据库中获得category_id之前,它无法将其分配给子集合。但第二次,category
有一个id,因此不需要立即刷新会话。nHibernate在不需要的时候不会和数据库聊天。正如我上面提到的,解决方案是总是使用事务来指定你什么时候完成你的工作。