使用 nhibernate 删除具有详细信息的实体级联删除孤儿,为什么我必须获取具有所有详细信息的实体,才能也删除它们?
假设我有以下实体:
public class Order
{
public int OrderID {get;set;};
public int Version {get;set;};
public IList<OrderDetail> Details {get;set;}
}
public class OrderDetail
{
public int OrderDetailID {get;set;}
/// Some other properties
}
当我想像这样删除实体时:
Order order = new Order { OrderID = 9, Version =1 };
ITransaction tr = Session.BeginTransaction();
Session.Delete(order);
tr.Commit();
订单已删除,但详细信息仍然存在,且 (OrderID) 外键设置为 null, 但是当我尝试像这样删除它时,它按预期工作:
Order order = Session.Get<Order>(9);
ITransaction tr = Session.BeginTransaction();
Session.Delete(order);
tr.Commit();
为什么我必须从数据库中获取整个实体才能删除它?
顺便说一句:我尝试创建一个 Order 实例并手动填写信息和详细信息,它也有效,
我不能做得尽可能简单吗?
Let's say I have the following entities:
public class Order
{
public int OrderID {get;set;};
public int Version {get;set;};
public IList<OrderDetail> Details {get;set;}
}
public class OrderDetail
{
public int OrderDetailID {get;set;}
/// Some other properties
}
When I want to delete the entity like this:
Order order = new Order { OrderID = 9, Version =1 };
ITransaction tr = Session.BeginTransaction();
Session.Delete(order);
tr.Commit();
Well the order is deleted, but the details is still there with (OrderID) foreign key set to null,
but when I try to delete it like this, it worked as expected:
Order order = Session.Get<Order>(9);
ITransaction tr = Session.BeginTransaction();
Session.Delete(order);
tr.Commit();
Why should I have to get the entire entity from database, in order to delete it?
BTW: I tried to create an instance of Order and fill the information and details information manually, it also worked
Can't I just do it as simple as possible ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,这种方法违背了 NHibernate 的原则。请参阅 Ayende(他是其背后的主要开发人员之一)对 此线程中的这个问题)
如果您正在使用 NHibernate 版本控制(看起来您是因为该 Version 属性的存在),那么无论如何您都必须从数据库获取 Order 项目,因为它不应该在没有提供正确版本号的情况下不允许您删除,并且在不检查数据库的情况下您如何知道它?
下面的想法可能有效:
以“NHibernate”方式创建对 Order 实体的引用。在不调用数据库的情况下引用持久实体的正确方法是使用 Session.Load 函数。这将返回相关实体的代理对象,如果需要,该实体可以从数据库中水合自身。您需要替换这一行:
with
您必须使用探查器或记录器进行检查,以查看在这种情况下订单是否实际上从数据库中重新水化(老实说,我认为会的)。
First, you are going against the principles of NHibernate with this approach. See Ayende's (he's one of the main developers behind it) response to this question in this thread)
If you are using NHibernate versioning (it looks like you are because of the presence of that Version property) then you will have to get the Order item from the database anyway because it shouldn't let you delete without the correct version number being provided and how would you know it without checking the database?
The idea below may work:
Create the reference to the Order entity the "NHibernate" way. The Correct way to reference a persisted entity without making a call to the database is to use the Session.Load function. This will return a proxy object of the entity in question which can hydrate itself from the database if needed. You would need to replace this line:
with
You will have to check with a profiler or logger to see if the Order was actually rehydrated from the database in this instance (which to be honest I think it will).