[英]Designing tables to avoid circular reference
当我设计数据库时,在一个项目(餐饮主题)中工作时,我什么都不在意,现在很难避免一些错误(循环错误)。
假设我有以下情形:
我有一个应该从半成品列表组成膳食对象(我们称之为产品 )和简单的资源列表。
一种产品由资源清单和产品清单组成。 因此,在实际示例中,它将如下所示:
膳食 :包含Resoruces ( 奶酪 , 面团 )列表和Products列表的Pizza:在我们的情况下将仅是:Sauce。 酱将由资源列表( 盐 , 一些 奶酪 , 番茄 酱 )和产品列表(在我们的情况下只是一个“加盐切碎的西红柿”)组成,所以现在我有以下课程:
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将由某种东西和产品2,产品4组成。
Product2将由东西和Prodcut3组成。
Prodcut 3将由东西和Prodcut4组成。
Prodcut 4将由东西和Prodcut1组成,在这种情况下,当我尝试计算Product1的成本或Product 4时,我将得到一个循环错误。
所以我的问题是在ProductToProduct表中。 我的问题是我必须如何设计表以避免这种错误。
非常抱歉,但很难解释这个问题。 如果不清楚,请问我。 感谢您的关注。
注意:对于这种情况,这并不是很重要,但是我正在ASP.Net mvc中工作,orm是Fluent Nhibernate。
这是一个函数示例,可用于检测是否存在父子关系。 我假设在称为ProductLink
的表中描述了产品关系,该表具有两个Product
外键: ParentProductId
和ChildProductId
。
此函数使用递归查询确定由参数@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
,您可以使用类似的测试来确定提议的父项和子项是否已经分别以子项和父项的形式存在于表中,如果允许,则不允许插入。
这只是一个简短的文章,以说明一种可能的方法。 我应该提及的是,我不知道随着表的变大,此功能的性能将如何扩展。 希望它能满足您的情况。 如果没有,请让我知道如何改善。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.