设计表以避免循环引用

时间:2014-05-23 16:22:31

标签: c# sql sql-server database fluent-nhibernate

在我设计数据库时在一个项目(Catering主题)中工作我没有关心某些事情,现在很难避免一些错误(循环错误)。

假设我有以下情况:

我的用餐对象应该由半成品 产品列表组成(我们称之为产品< / strong>)以及简单资源的列表。

一个产品 Resoruces 列表和产品列表组成。 所以在实际例子中,这将是这样的:

用餐:包含 Resoruces 奶酪面团)列表和列表的披萨产品:在我们的案例中将只是:酱。 酱料将由资源列表组成(一些 奶酪番茄 )和产品列表(在我们的例子中只是一个“带盐的切碎的西红柿”) 所以现在我有以下课程:

public class Resource
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }


    public class ProductToProduct
    {
        public int Id { get; set; }
        public Product MainProduct { get; set; }
        public Product Component { get; set; }
        public double Quantity { get; set; }
    }

    public class ProductToResource
    {
        public int Id { get; set; }
        public Product Product { get; set; }
        public Resource Resource { get; set; }
        public double Quantityt { get; set; }
    }

    public class Meal
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public IList<MealToProduct> MealToProducts { get; set; }
        public IList<MealToResource> MealToResources { get; set; }

    }

    public class MealToResource
    {
        public int Id { get; set; }
        public Meal Meal { get; set; }
        public Resource Resource { get; set; }
        public double Quantity { get; set; }

    }


    public class MealToProduct
    {
        public Meal Meal { get; set; }
        public Product Product { get; set; }
        public double Quantity { get; set; }
    }

    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public IList<ProductToResource> ProdcutToResources { get; set; }
        public IList<ProductToResource> ProductToProducts { get; set; }

    }

我的问题与产品与产品有关。

假设我将拥有Product1,Product2,Product3,Product4。

产品1将由Prodcut2,Product4组成。

Product2将由一些东西和Prodcut3组成。

产品3将由某些东西和Prodcut4组成。

Prodcut 4将由一些东西和Prodcut1组成,在这种情况下,当我尝试计算Product1或Product 4的成本时,我会收到一个循环错误。

所以我的问题出在ProductToProduct表中。 我的问题是如何设计表来避免这种错误。

我对我的探索非常抱歉,但我很难解释这个问题。 如果有些不对劲,请问我。 感谢您的注意。

注意:这对于这种情况并不那么重要,但我在ASP.Net mvc中工作,orm是Fluent Nhibernate。

1 个答案:

答案 0 :(得分:1)

这是一个可用于检测父子关系是否存在的函数示例。我假设产品关系在名为ProductLink的表中描述,该表有Product的两个外键:ParentProductIdChildProductId

此函数使用recursive query来确定由参数@ParentProductId表示的产品子项的完整产品列表,然后进行简单测试以查看@ChildProductId是否出现在那份清单。

create function dbo.ProductRelationshipExists
(
    @ParentProductId int,
    @ChildProductId int
)
returns bit
as
begin
    declare @ChildExists bit = 0;

    with ProductChildCTE as
    (
        -- Base case: Get the parent's direct children.
        select ChildProductId from ProductLink where ParentProductId = @ParentProductId

        -- Recursive case: Get the children's children.
        union all
        select
            ProductLink.ChildProductId
        from
            ProductChildCTE
            inner join ProductLink on ProductChildCTE.ChildProductId = ProductLink.ParentProductId
    )
    select @ChildExists = 1 from ProductChildCTE where ChildProductId = @ChildProductId;

    return @ChildExists;
end

当有人试图将记录插入ProductLink时,您可以使用这样的测试来确定建议的父级和子级是否已分别作为子级和父级位于表中,如果是,则禁止插入

这只是一个快速的记录,以说明一种可能的方法;我应该提一下,我不知道随着桌子越来越大,这个东西的表现会有多大。希望它足以满足您的需求。如果没有,请告诉我如何改进它。