LINQ Lambda 返回父项,其中子项 ID 在 int 列表中

问题描述 投票:0回答:2

我有一个矩阵和位置的父/子模式,我想在位置 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)以及我自己的知识。

提前致谢

罗布

c# entity-framework linq
2个回答
1
投票

如果您在上下文中正确设置了关系,您可以尝试:

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();

0
投票

因为你只从一个表中选择数据(

select m.*
)我你想要来自
m
的不同记录。在那种情况下,您的原始代码会产生预期的结果(
exists
select distinct m.* ... join ...
更有效)。

© www.soinside.com 2019 - 2024. All rights reserved.