查找一个列表中具有与另一个对象列表中的属性匹配的属性的所有对象
Posted
技术标签:
【中文标题】查找一个列表中具有与另一个对象列表中的属性匹配的属性的所有对象【英文标题】:Find all objects in one list that have a property that matches a property in another list of objects 【发布时间】:2020-06-09 09:47:54 【问题描述】:问题
我正在尝试使用另一个表(基于 ModelB)查询一个表(基于 ModelA
)。对于此示例,这些模型进行了简化。我需要将结果保留为IQueryable
,因此更改为Enumerable
或List
不是选项。不过,我尝试添加.ToList()
,但得到了同样的错误。
将MyId
s 从一个列表中拉到一个字符串列表中(以便使用Contains()
)不是一种选择,因为可能有太多MyIds
(> 40k)会导致错误指示资源耗尽的操作,我猜是指 RAM。
错误
InvalidOperationException:无法翻译 LINQ 表达式 ...。以可翻译的形式重写查询,或通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估。
模型A
public class ModelA
public string MyId get; set;
public string MyName get; set;
模型B
public class ModelB
public string MyId get; set;
public string MyName get; set;
尝试
var results = context.ModelA
.Where(a => ModelB.All(b => b.MyId == a.MyId));
什么方法可以成功?
【问题讨论】:
var results = context.ModelA.Where(a => ModelB.Any(b => b.MyId == a.MyId));
是的,Any
是正确的方法。谢谢。
【参考方案1】:
您可以尝试检查第二个列表是否包含匹配 ID 的“Any()”
var results = context.ModelA
.Where(a => ModelB.Where(b => b.MyId == a.MyId).Any());
或者您可能想尝试加入
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/join-clause
var results = context.ModelA
.Where(a => ModelB.
Any(b => b!= null && b.id != null
&& a!=null && a.id!==null &&
b.MyId == a.MyId));
我有 Select 而不是 Where 并且我检查了空值
【讨论】:
两个选项都有效,但Join
选项比Where
慢,所以我选择了更快的选项。我必须为ModelB
创建一个视图,以便可以从与ModelA
相同的上下文访问它(它们位于不同的数据库中)。从一开始就选择你的答案。【参考方案2】:
有一些方法可以实现,这里有两种方法供大家参考:
var result = (from a in context.ModelA
join b in context.ModelB
on a.MyId equals b.MyId
select a);
或者你可以试试这个方法:
var result = context.ModelA.Join(_context.ModelB,
x => x.MyId,
y => y.MyId,
(x, y) => x);
您可以参考this link了解更多详情。
【讨论】:
谢谢,我试过Join
,它成功了。由于某种原因,它比Where
慢一点。我还必须为ModelB
创建一个视图,以便可以从与ModelA
相同的上下文访问它(它们位于不同的数据库中)。【参考方案3】:
你可以试试这个:
var results = ctx
.ModelAs
.Where(ma => ctx.ModelBs.Any(mb => mb.MyId == ma.MyId));
我用过你的模型,这是我的DbContext
:
public class MockContext : DbContext
public MockContext(DbContextOptions<MockContext> options)
: base(options)
public DbSet<ModelA> ModelAs get; set;
public DbSet<ModelB> ModelBs get; set;
我用来测试的数据是:
模型A:
MyId | MyName
1 Nettie Koch
2 Karl Kuvalis
3 Marcus Weissnat
4 Shannon Hettinger
5 Wilma Kuvalis
6 Benny Brown
7 Amanda Maggio
8 Claude Kohler
9 Dawn Ritchie
10 Alan Ruecker
模型B:
MyId | MyName
5 Francis Konopelski
6 Mandy Yost
7 Marsha Parisian
8 Crystal Mayer
9 Sergio Crona
10 Kenny Rice
11 Levi Gutkowski
12 Brandon Haley
13 Jan Kunze
14 Rafael Blanda
结果:
MyId | MyName
5 Wilma Kuvalis
6 Benny Brown
7 Amanda Maggio
8 Claude Kohler
9 Dawn Ritchie
10 Alan Ruecker
【讨论】:
很好,彻底的答案,谢谢。我必须为ModelB
创建一个视图,以便可以从与ModelA
相同的上下文访问它(它们位于不同的数据库中)。【参考方案4】:
您可能正在查看Any()
,如下所示
var results = context.ModelA.Where(a => ModelB.Any(b => b.MyId == a.MyId));
【讨论】:
正如我在评论部分提到的。您可以使用Any()
来实现它。如果对你有帮助,别忘了接受我的回答。以上是关于查找一个列表中具有与另一个对象列表中的属性匹配的属性的所有对象的主要内容,如果未能解决你的问题,请参考以下文章
Grails:查找具有列表属性的对象,其中包含具有给定属性值的对象