【问题标题】:LINQ method with multiple conditions and combinations具有多个条件和组合的 LINQ 方法
【发布时间】:2019-03-15 06:19:59
【问题描述】:

假设我有一个包含 1000 个条目的详细信息列表类。如何使用结合 FirstCode 和 SecondCode 属性的 LINQ 方法从数据库详细信息表中准确检索匹配数据?

public class Detail
{
  public string FirstCode  { get; set; }
  public string SecondCode { get; set; }
}

如果我们要检索单个数据,它会是这样的:

foreach(var detail in details)
{
    var retrievedData = context.Details
        .Where(x => x.FirstCode == detail.FirstCode && x.SecondCode == detail.SecondCode)
        .FirstOrDefault();

    // Add to some list here
}

但我不想从数据库中获取 1000 次,也不想从 Details 表中获取所有数据,然后在 .NET 级别内进行搜索,因为如果我们有一堆数据(例如,详细信息表中的 500,000 多条记录)。

【问题讨论】:

  • 您的Where() 子句将生成正确的SQL 语句,该语句只返回数据库中的相关行。这就是 Linq-to-Entities(EntityFramework 的一部分)的目的。
  • 根据 detail.Firstcode 和 detail.SecondCode 将您的详细信息与详细信息相结合,并立即检索最终结果
  • 为什么要在数据库中查询 2000 个值?你不能在临时表中插入这些值,然后使用连接选择你想要的数据吗?
  • 您有 2 个选项。您可以使用table valued parameter (example2),这是更多代码,但如果您在这些值上使用索引,则性能会更高,因为它会导致使用索引查找。或者您可以连接查找中的值(第一个+第二个)并创建一个字符串数组并使用 Contains 并将数据库表中的值连接为 contains 调用的输入。这更容易做到,但性能较差,因为它本质上会导致表扫描。
  • 我在 CodeCaster 工作。尝试使用 2000 个过滤器值编写查询是巨大的,并且强烈建议这是一个XY problem。建议的解决方案 (Y) 不好,您应该询问您要解决的 X 问题。

标签: c# performance entity-framework linq


【解决方案1】:

您需要以编程方式生成“where”子句。从返回 Details 数据库表中所有行的查询开始...

IQueryable<XDetail> queryable = (from d in context.Details select d);

...其中 XDetail 是数据库表的类类型。我认为它与您问题中的 Detail 类不同。现在您需要为查询生成所有子句,以指定我们想要的条目列表...

var predicate = PredicateBuilder.False<XDetail>();
foreach(Detail d in details)
    predicate = predicate.Or((xd) => xd.FirstCode == d.FirstCode && 
                                     xd.SecondCode == d.SecondCode));

queryable = queryable.Where(predicate);
var results = queryable.ToList();

您可以查看 PredicateBuilder 类 here 的代码。请注意,Entity Framework 将生成所需的 SQL,但该查询的大小是有限制的。因此,添加 1000 条子句肯定会变大。您必须进行试验,但在达到限制之前,您可能会被限制在 100 或更少。

【讨论】:

  • 超级好用! (也许您也可以将 PredicateBuilder 添加到答案中)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多