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。

或者,如果有人有更好的想法来存储兼容性数据,我也支持这个解决方案。

附言:对不起我的英语

SQL Server、LINQ、C#存储数据链信息

好的,我认为没有简单的方法可以做到这一点,但我可以找到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);