SQL转LINQ方法咨询:多对多关系下SQL转C# LINQ求助
没问题!我来帮你搞定多对多关系下SQL转LINQ的事儿~ 先默认你用的是Entity Framework(不管是EF Core还是EF6),这类ORM一般会自动处理中间的ProductCategory关联表,给Product和Category实体配上导航属性,比如Product.Categories和Category.Products。下面我拿几个最常见的SQL场景举例,你可以对着自己的需求调整:
对应的SQL通常是这样的:
SELECT p.ProductId, p.ProductName, c.CategoryId, c.CategoryName
FROM Product p
JOIN ProductCategory pc ON p.ProductId = pc.ProductId
JOIN Category c ON pc.CategoryId = c.CategoryId
转换成LINQ的话,有两种常用写法:
查询语法(类似SQL的写法,可读性强)
var productCategoryQuery = from p in context.Products from c in p.Categories select new { p.ProductId, p.ProductName, c.CategoryId, c.CategoryName };
方法链语法(更简洁,适合链式操作)
var productCategoryQuery = context.Products .SelectMany(p => p.Categories, (p, c) => new { p.ProductId, p.ProductName, c.CategoryId, c.CategoryName });
比如要找分类ID为1的所有产品,对应的SQL:
SELECT p.*
FROM Product p
JOIN ProductCategory pc ON p.ProductId = pc.ProductId
WHERE pc.CategoryId = 1
LINQ写法:
查询语法
var targetCategoryId = 1; var productsInCategory = from p in context.Products where p.Categories.Any(c => c.CategoryId == targetCategoryId) select p;
方法链语法
var targetCategoryId = 1; var productsInCategory = context.Products .Where(p => p.Categories.Any(c => c.CategoryId == targetCategoryId));
如果想直接拿到每个产品对象,同时加载它关联的所有分类(而不是拆成一条条数据),可以用EF的Include方法实现预加载:
查询语法
var productsWithCategories = from p in context.Products.Include(p => p.Categories) select p;
方法链语法
var productsWithCategories = context.Products.Include(p => p.Categories);
如果你的项目没有用EF的导航属性,需要直接操作ProductCategory表,那可以手动JOIN三张表:
var manualJoinQuery = from p in context.Products join pc in context.ProductCategories on p.ProductId equals pc.ProductId join c in context.Categories on pc.CategoryId equals c.CategoryId select new { p.ProductId, p.ProductName, c.CategoryId, c.CategoryName };
如果你的实际SQL和上面的场景不一样,可以把具体的SQL贴出来,我再帮你调整对应的LINQ写法~
内容的提问来源于stack exchange,提问作者Sejn

