1

我在对象ProductSupplier. 我需要能够在Supplier不删除Product属于它的 s 的情况下删除。

这是类的简化版本:

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 表上创建一个外键,因此当我尝试对供应商进行直接删除时,我会收到外键约束错误。我尝试将级联更改为“全部”,希望它可能只删除关系,但它删除了所有产品及其其他关联对象。

我现在能看到解决这个问题的唯一方法是迭代供应商的产品集合并将供应商属性设置为空。有没有办法通过映射实现这种行为?

4

2 回答 2

2

映射属性仅在实体实际加载时生效,并且在您不通过 HQL 查询时生效。例如,如果您指定Cascade=ALL,如果您使用 query 删除供应商"delete from Supplier where id=:id",您可能会遇到相同的 FK 约束失败,因为 hql 不会触发(程序化)级联。

似乎产品是关系的拥有方,这很好。我认为你有两个选择:

  • 在供应商上编写一些方法来遍历所有产品并将产品的供应商设置为空,并在删除任何供应商之前使用此方法
  • 在发出供应商删除之前,请确保您的 DAO 将产品的供应商设置为 null

例子:

public int Delete(Supplier s) {
    return Session.CreateQuery("udpate Product set Supplier = null where Supplier = :supplier")
        .SetParameter("supplier", s)
        .ExecuteUpdate();
}
于 2009-04-29T10:44:24.650 回答
0

不要这样做。

您的模型中有一个隐含或明确的断言,即所有产品都有一个供应商。外键用于强制执行此条件。在保留产品的同时删除供应商违反了您的模型,并且可能会导致您的大部分代码(依赖于始终正确)失败。

您可以做的一件事,您已经发现:对于具有此供应商的每个产品,您可以将产品的供应商设置为空。这不会违反你的条件,但相当于说“我们不知道这个产品的供应商是谁”,可能会导致代码失败。

你为什么要这样做?

于 2009-04-29T11:16:47.180 回答