dapper 中的多对多多重映射
这是我的数据库
Product
+----+----------+
| Id | Name |
+----+----------+
| 1 | Product1 |
| 2 | Product2 |
| 3 | Product3 |
+----+----------+
Category
+----+-----------+
| Id | Name |
+----+-----------+
| 1 | Category1 |
| 2 | Category2 |
| 3 | Category3 |
+----+-----------+
ProductCategory
+----+------------+------------+
| Id | ProductId | CategoryId |
+----+------------+------------+
| 1 | 1 | 1 |
| 2 | 1 | 1 |
| 3 | 2 | 2 |
+----+------------+------------+
现在,我想获取所有产品及其类别。在我的存储库中,我添加了以下代码:
public async Task<IEnumerable<Product>> GetAllProducts()
{
var products = await _dbConnection.QueryAsync<Product, Category, Product>(
@"
SELECT p.Id, p.Name, c.Id, c.Name
FROM Product p
LEFT JOIN ProductCategory pc on pc.ProductId = p.Id
LEFT JOIN Category c on c.Id = pc.CategoryId
",
(product, category) =>
{
product.Categories.Add(category);
return product;
}, splitOn: "Id",
transaction: _dbTransaction
);
return products.GroupBy(p => p.Id).Select(g =>
{
var product = g.First();
product.Categories = g.Select(p => p.Categories.Single()).ToList();
return product;
});
}
在结果中,我得到了 3 个项目的列表:
- Product1 有 2 个类别(Category1、Category2)
- Product2 有 1 个类别(Category2)
- Product3 有 1 个类别(null)
问题是我不想要Product3 使用 null
值填充类别列表。我想要的是在这种情况下有空的类别列表。我应该做什么才能实现这一目标?
This is my database
Product
+----+----------+
| Id | Name |
+----+----------+
| 1 | Product1 |
| 2 | Product2 |
| 3 | Product3 |
+----+----------+
Category
+----+-----------+
| Id | Name |
+----+-----------+
| 1 | Category1 |
| 2 | Category2 |
| 3 | Category3 |
+----+-----------+
ProductCategory
+----+------------+------------+
| Id | ProductId | CategoryId |
+----+------------+------------+
| 1 | 1 | 1 |
| 2 | 1 | 1 |
| 3 | 2 | 2 |
+----+------------+------------+
Now, I want to get all products with its categories. In my repository I added this code:
public async Task<IEnumerable<Product>> GetAllProducts()
{
var products = await _dbConnection.QueryAsync<Product, Category, Product>(
@"
SELECT p.Id, p.Name, c.Id, c.Name
FROM Product p
LEFT JOIN ProductCategory pc on pc.ProductId = p.Id
LEFT JOIN Category c on c.Id = pc.CategoryId
",
(product, category) =>
{
product.Categories.Add(category);
return product;
}, splitOn: "Id",
transaction: _dbTransaction
);
return products.GroupBy(p => p.Id).Select(g =>
{
var product = g.First();
product.Categories = g.Select(p => p.Categories.Single()).ToList();
return product;
});
}
In results, I got list of 3 items:
- Product1 with 2 categories (Category1, Category2)
- Product2 with 1 category (Category2)
- Product3 with 1 category (null)
The problem is that I don't want Product3 to have filled category list with null
value. What I wanted is to have empty Category list in this case. What should I do to achieve that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为什么不直接将映射函数更改为?:
对于
GroupBy
中的.Single()
来说,这当然会失败,但是无论如何,您将如何按缺失的类别进行分组呢?Why not just change the mapping function to?:
That will of course fail for the
.Single()
inGroupBy
, but how would you group by missing category anyway?首先从查询中返回原始数据,然后进行一些处理会更容易。然后你就可以将所有逻辑集中在一处。例如:
null 检查会跳过由于外连接而不可避免地出现在 SQL 结果集中的
null
类别。It's easier to return the raw data from the query first and then do some processing. Then you have all logic in one place. For example:
The null check skips the
null
category that's inevitably in the SQL result set because of the outer joins.