【问题标题】:LINQ where db table does not contain in memory list elementsLINQ,其中 db 表不包含内存列表元素
【发布时间】:2013-05-13 23:19:12
【问题描述】:

我见过theseStackOverflowAnswers,但是当过滤列表在内存中时,它们不会产生相同的结果。

我有一个 ID 列表。我想删除数据库中存在的任何 ID,以便留下需要添加的 ID 列表。换句话说,我需要使用 Linq-To-Entities 执行where not in SQL 查询。问题是,这些方法不是产生那个 SQL,而是每个方法产生一个 SQL 查询每个列表项

var providerIds = new [] {"1130", "1", "16"};

方法一

var missingProviders = (from provider in providerIds
                        where !JobProviders.Any(p => p.JobProviderID == provider)
                        select provider).ToList();

方法二

var missingProviders = (from provider in providerIds
                        where !(from p in JobProviders select p.JobProviderID).Contains(provider)
                        select provider).ToList();

有没有办法构建 LINQ 查询以生成预期的not in 表单,或者这些是唯一的解决方案吗?

【问题讨论】:

  • 你找到解决这个问题的方法了吗?
  • @Arthur,不,我没有。我没有使用 LINQ,因为似乎没有办法做到这一点。

标签: c# linq-to-entities


【解决方案1】:

类似的东西呢

var providersInDb = (from provider in JobProviders
                     where providerIds.Contains(provider.JobProviderID)
                     select provider.JobProviderID).ToList();

var missingProviders = providerIds.Where(p => !providersInDb.Contains(p))

【讨论】:

  • 实际上,这就是我现在正在做的事情,但问题是我正在加倍工作。如果providerIdsprovidersInDb 的列表都很大,那么数据库正在执行查找工作,发回一个大列表,然后客户端也在过滤它。理想情况下,大的providerIds 列表将进入数据库,它会进行所有过滤,然后只发回missingProviders
  • 因此使用 1k 的列表进行测试,这与 SQL 的 not in 查询之间存在巨大的性能差异。
【解决方案2】:

棘手。我面前没有我的工具,所以我不知道这将如何实现。

var dbProviderIds = JobProviders.Select(p => p.JobProviderId);
var allProviders = dbProviderIds.Union(providerIds).Distinct();
var missing = allProviders.Except(dbProviderIds);

在数据库上,获取所有提供者 ID,然后将其与内存中的 ID 结合起来。然后删除数据库中已知的那些。

【讨论】:

  • 这与上一个答案有相同的缺陷:从数据库中提取 all 的 Id 来执行这一步,性能很糟糕。整个目的是通过将列表发送到数据库并仅返回需要的内容来避免这样做。它也没有回答让 LINQ 生成not in SQL 查询的问题。
猜你喜欢
  • 1970-01-01
  • 2012-05-26
  • 2012-08-24
  • 1970-01-01
  • 1970-01-01
  • 2020-03-27
  • 1970-01-01
  • 2016-12-06
  • 1970-01-01
相关资源
最近更新 更多