12

我有两个类“产品”和“卖家”。

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }

    public Seller Seller { get; set; }
    public int? SellerId { get; set; }
}
public class Seller
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Product> Products { get; set; }
}

我想使用 dapper 提取所有产品的卖家列表。

目前我正在这样做:

Dictionary<int, Seller> dic = new Dictionary<int, Seller>();
        Conn.Query<Seller, Product, int>
            (@"select s.*,p.* from Sellers s Join Products p 
                on p.SellerId = s.Id",
            (s, p) => {
                if (dic.ContainsKey(s.Id))
                    dic[s.Id].Products.Add(p);
                else
                {
                    s.Products = new List<Product>();
                    s.Products.Add(p);
                    dic.Add(s.Id, s);
                }
                return s.Id; 
            });
        var sellers = dic.Select(pair => pair.Value);

有没有更好的办法?

4

2 回答 2

3

我认为您将存储数据的方式与使用数据的方式混合在一起。我建议规范化你的数据库。

//Normalized Database classes
public class Seller
{
    public int Id { get; set; }  // primary key
    public string Name { get; set; }
}

public class Product
{
    public int Id { get; set; }  // primary key
    public int SellerId { get; set; } // foreign key
    public string Name { get; set; }
    public decimal Price { get; set; }
}

然后就可以直接查询 Seller 和 product 表了。

var Sellers = connection.Query<Seller>("Select * from Seller");
var Products = connection.Query<Product>("Select * from Product");

然后使用 linq "group by" 将 Product 放入字典中

var SellerWithProductsDict = 
        (from prod
        in Products 
        group prod by prod.SellerId
        into groupedProducts
        select groupedProducts)
        .ToDictionary(gp => gp.SellerId, gp => gp.ToList());

然后你可以通过 SellerWithProductsDict 循环查看所有卖家产品,如果你需要卖家名称,只需从 Sellers 查询结果中通过索引获取它

******************************************

这就是答案的结尾,但是如果您真的需要将产品与卖家混合,您可以使用上面相同的数据库结构并执行以下操作:

var qry = @"Select s.Id as SellerId,
                   s.Name as SellerName,
                   p.Id as ProductId,
                   p.Name as ProductName,
                   p.Price as ProductPrice
            From Seller as s, Product as p
            Where s.Id = p.id"

var SellerWithProducts = connection.Query(qry)

然后使用 linq "group by" 函数将其放入字典中。我建议查看此“ Linq group-by multiple fields ”帖子以获取 linq 组的帮助

于 2012-11-13T06:02:40.740 回答
1

由于某种原因,我的上一篇文章发疯了。

首先,从数据库中获取所有内容可能是个坏主意。您可能需要考虑限制您的查询。即使您的桌子现在可能很小,您也不想将自己靠在墙上。

话虽如此,我建议通过在卖方和产品上添加静态方法来简化获取卖方和产品的代码。

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }

    public int? SellerId { get; set; }
    public Seller Seller { get; set; }

    public static Product GetProductById(int id)
    {
        Product product = null;
        using (SqlConnection connection = new SqlConnection("connectionString"))
        {
            product = connection.Query<Product>("select * from Product where Id = @Id", new { Id = id }).SingleOrDefault();
            product.Seller = connection.Query<Seller>("select * from Seller where Id = @Id", new { Id = product.SellerId }).SingleOrDefault();
        }

        return product;
    }
}

public class Seller
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Product> Products { get; set; }

    public static Seller GetSellerById(int id)
    {
        Seller seller = null;
        using (SqlConnection connection = new SqlConnection("connectionString"))
        {
            seller = connection.Query<Seller>("select * from Seller where Id = @Id", new { Id = id }).SingleOrDefault();
            if(seller != null)
            {
                seller.Products = connection.Query<Product>("select * from Product where SellerId = @Id", new { Id = id }).ToList();
                seller.Products.ForEach(p => p.Seller = seller);
            }
        }

        return seller;
    }
}

请记住,这很粗略,并不能代表您可能需要的一切,但从长远来看,它更容易使用,并且比使用查询来获取数据更好地遵循面向对象的设计。

您可以通过添加查询有关卖家或产品的其他信息的方法(例如 GetSellersInZipCode(int zipCode) 并通过该方法返回一个列表)来进一步扩展此想法。

于 2012-11-09T21:54:05.707 回答