我有一个矩阵和位置的父/子模式,我想在位置 Id int 列表中传递,然后返回连接上的矩阵记录,在 SQL 中这返回我需要的:
select m.* from locationmatrices lm
inner join matrices m on lm.MatrixId = m.Id
where lm.LocationId in (1, 8, 29, 68)
我写了这个 LINQ lambda 但它没有像我期望的那样设置连接
var locationIdss = new List<int> { 1, 8, 29, 68 };
matrices.Where(p => p.LocationMatrices.Where(_ => locationIds.Contains(_.Id)).Any());
生成的 SQL 明显错误:
SELECT [m].[Id], [m].[Archived], [m].[DateCreated], [m].[Description], [m].[Name]
FROM [Stock].[Matrices] AS [m]
WHERE [m].[Archived] = CAST(0 AS bit) AND EXISTS (
SELECT 1
FROM [Stock].[LocationMatrices] AS [l]
WHERE [m].[Id] = [l].[MatrixId] AND [l].[Id] IN (8, 68, 29, 1))
我用查询语法编写了 LINQ,效果很好:
var foo = from matrixes in _stockContext.Matrices.AsQueryable<Matrix>()
join location in _stockContext.LocationMatrices.AsQueryable<LocationMatrix>() on matrixes.Id equals location.MatrixId
where locationIds.Contains(location.LocationId)
select matrixes;
我只是想知道如何在 LINQ Lambda 中编写它,以保持代码库的一致性(因为它是所有 LINQ lambda)以及我自己的知识。
提前致谢
罗布
如果您在上下文中正确设置了关系,您可以尝试:
var lms = _stockContext.LocationMatrices
.Where(l => locationIds.Contains(l.LocationId))
.Include(l => l.Matrix) // assuming this exists
.Where(l => l.Matrix != null)
.ToList();
var result = lms
.Select(l => l.Matrix)
.ToList();
否则我会争辩说,用方法语法重写查询不会那么漂亮,我个人会坚持使用查询语法。
更新
错过了只需要
Matrix
数据,所以尝试简化查询:
var lms = _stockContext.LocationMatrices
.Where(l => locationIds.Contains(l.LocationId))
.Where(l => l.Matrix != null)
.Select(l => l.Matrix)
.ToList();
因为你只从一个表中选择数据(
select m.*
)我猜你想要来自m
的不同记录。在那种情况下,您的原始代码会产生预期的结果(exists
比 select distinct m.* ... join ...
更有效)。