我在对象Product
和Supplier
之间存在多对一关系。我需要能够删除Supplier
而不删除属于它的Product
。
以下是类的简化版本:
public class Supplier {
public virtual IList<Product> Products { get; protected set; }
}
public class Product {
// Product belongs to a Category but Supplier is optional
public virtual Supplier Supplier { get; set; }
public virtual Category Category { get; set; }
}
我正在使用FluentNHibernate,但这是它产生的映射:
<bag name="Products" cascade="save-update" inverse="true">
<key column="SupplierID" />
<one-to-many class="Me.Product, Me, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</bag>
<many-to-one name="Supplier" column="SupplierID" />
这会在Products表上创建一个外键,因此当我尝试在Supplier上进行直接删除时,会出现外键约束错误。我尝试将级联更改为'all',希望它可能只删除关系,但它删除了所有产品及其他相关对象。
我现在能够看到解决此问题的唯一方法是迭代Supplier的Products集合并将Supplier属性设置为null。有没有办法通过映射实现这种行为?
答案 0 :(得分:2)
映射属性仅在实际加载实体时以及未通过HQL查询时生效。例如,如果指定Cascade=ALL
,如果删除带有查询"delete from Supplier where id=:id"
的供应商,则可能会遇到相同的FK约束失败,因为hql不会触发(编程)级联。 / p>
似乎产品是关系的拥有方,这很好。我认为你有两个选择:
示例:
public int Delete(Supplier s) {
return Session.CreateQuery("udpate Product set Supplier = null where Supplier = :supplier")
.SetParameter("supplier", s)
.ExecuteUpdate();
}
答案 1 :(得分:0)
请勿这样做。
您的模型中有一个隐含或显式断言,所有产品都有供应商。外键是为了强制执行这种情况。在保留产品的同时删除供应商会违反您的模型,并可能导致您的大部分代码(依赖于此始终如此)失败。
您可以做的一件事是,您已经发现:对于拥有此供应商的每个产品,您都可以将产品供应商设置为空。这不会违反您的条件,但与“我们不知道该产品的供应商是谁”相同并且可能导致代码失败。
你为什么要这样做?