SQL Server、LINQ、C#存储数据链信息
本文关键字:数据 存储 信息 Server LINQ SQL | 更新日期: 2023-09-27 18:26:49
我想存储有关兼容产品的信息。我有两个表,一个用于product_id的products,另一个用于它的连接。
表格结构如下:
+---------+------------+
| Product | Compatible |
+---------+------------+
| id | id |
| name | prod1_id |
| price | prod2_id |
+---------+------------+
因此,当产品1与产品3兼容时,我将id:1&3.当产品1与产品5兼容时,我插入id:1&5.
兼容性是双向的,所以如果我插入上面的记录,我还定义了产品5和产品3与产品1兼容。
问题来了,当我插入与产品6:id,3,6兼容的产品3的数据时,稍后我需要一个列表,关于哪些产品与产品1兼容。在这种情况下,列表必须包含3,5,6(因为3和6之间的连接)。
由于有大量的产品和连接,我需要一个聪明的方法来查询这个"兼容性链"。
有人能给我提个好办法吗?即使在clear SQL中或在客户端使用C#和LINQ。
或者,如果有人有更好的想法来存储兼容性数据,我也支持这个解决方案。
附言:对不起我的英语
好的,我认为没有简单的方法可以做到这一点,但我可以找到Linq、递归方法和foreach循环的组合。
假设你有这两个类:
public class Compatible
{
public string Prod1_id;
public string Prod2_id;
}
public class Product
{
public string Id;
}
我们有一个兼容产品列表,代表您的"兼容"表。您需要实现一种方法,以获得单个产品的所有直接兼容产品:
static List<string> GetCompatibles(IEnumerable<Compatible> table,
string productId, string originalId, List<string> addedProducts)
{
return table.Where(c =>
(c.Prod1_id == productId &&
c.Prod2_id != originalId &&
!addedProducts.Contains(c.Prod2_id))
).Select(c => c.Prod2_id).ToList();
}
然后,找到了一个递归方法,它对每个兼容的"子"产品调用GetCompatibles:
static List<string> GetAllCompatibles(List<Compatible> table,
Product product, Product originalProduct, List<string> addedProducts)
{
List<string> result = new List<string>();
//Gets all the directly compatible products
var Childs = GetCompatibles(table, product.Id, originalProduct.Id, addedProducts);
//Gets all the directly compatible products by retrocompatibility
Childs.AddRange(GetCompatibles(table.Select(t =>
new Compatible { Prod1_id = t.Prod2_id, Prod2_id = t.Prod1_id }
).ToList(), product.Id, originalProduct.Id, addedProducts));
result.AddRange(Childs);
addedProducts.AddRange(Childs);
//Iterates over the directly compatible products
foreach (string child in Childs)
{
//Again, get all the directly compatible products of the "child"
var temp = GetAllCompatibles(table, new Product { Id = child },
originalProduct, addedProducts);
result.AddRange(temp);
//If there are childs compatible products, adds it to the final result
if (temp.Count > 0)
{
result.AddRange(temp.Select(p =>
GetCompatibles(table, p, originalProduct.Id, addedProducts)
).Aggregate((l1, l2) =>
{ l1.AddRange(l2); return l1; })
);
}
}
return result.Distinct().ToList();
}
不简单,不优雅,但是嘿。。。它有效!
进行这样的主调用:
Product product = new Product { Id = "1" };
//List to avoid stack overflow exceptions
List<string> addedProducts = new List<string>();
//Gets all the compatible products 1 -> X and X-> 1
List<string> compatibility = GetAllCompatibles(table, product, product, addedProducts);