【问题标题】:Entity Framework building Where clause on the fly using Expression实体框架使用表达式即时构建 Where 子句
【发布时间】:2016-05-06 17:30:54
【问题描述】:

使用实体框架 C# 并有这个查询,我需要它说的部分:

where x.Login_Status == "Submitted"

是动态的。在不同的情况下,它可能是“已提交”或 null 或其他内容,而不是编写具有不同查询的多个 if 语句,而是希望在 where 子句中有一个谓词。

status = (from x in ctx.table
          where x.Login_Status == "Submitted"
          orderby x.SUB_DATE descending
          select new Model_Table()
          {
              Id = x.ID,
              Name = x.NAME,
              Code = x.Code,
              DateSubmitted = x.SUB_DATE
           }).ToList<Model_Table>();

这可能吗?

解决方案:

if语句里面遇到更多参数的时候用这个

where_expression = x => x.Login_Status == "Submitted" || x.Login_Status == null;

这是一个对我有用的完整代码,方括号之间的任何内容都替换为适合您的代码:

Expression<Func<[Replace with your Entity], bool>> where_submitted = x => x.Login_Status == "Submitted";

// Check if all selected
if (CheckBox_Show_All_Submitted.Checked)
{
    where_submitted = x => x.Login_Status == "Submitted" || x.Login_Status == null;
}

status = 
    ctx.[Replace with your Entity Table]
    .Where(where_submitted)
    .OrderByDescending(x => x.SUB_DATE)
    .Select(x => new Model_Table
        {
           Id = x.ID,
           Name = x.NAME,
           Code = x.Code,
           DateSubmitted = x.SUB_DATE
        }).ToList<Model_Table>();

【问题讨论】:

标签: c# mysql entity-framework visual-studio predicate


【解决方案1】:

您需要Expression&lt;Func&lt;Entity,bool&gt;&gt;,而不是Predicate&lt;Entity&gt;。区别在于谓词是编译的委托,而表达式是代码即数据,因此可以转换为 SQL。

这是一个例子:

//You can have this expression have different values based on your logic
Expression<Func<Entity,bool>> where_expression = x => x.Login_Status == "Submitted";

var query =
    ctx.Table
    .Where(where_expression)
    .OrderByDescending(x => x.SUB_DATE)
    .Select(x => new Model_Table())
    {
        Id = x.ID,
        Name = x.NAME,
        Code = x.Code,
        DateSubmitted = x.SUB_DATE
   }).ToList();        

请注意,Entity 需要替换为真实类的名称。

【讨论】:

  • 这真的很有帮助。有一个小问题。使用此表达式时 Expression> where_expression = x => x.Login_Status == "Submitted";它仅适用于“提交”值,但我需要同时拥有“提交”和 null。
  • 表达式中可以有任何条件。例如。你可以有x =&gt; x.Login_Status == "Submitted" || x.Login_Status == null
【解决方案2】:

像这样为 IQueryable 创建一个扩展方法:

public static class MethodExtensions{

      public static IEnumerable<Model_Table> Query(this IQueryable<TEntity> source, string data){
             return (from x in source
             where x.Login_Status == data
             orderby x.SUB_DATE descending
             select new Model_Table()
            {
                Id = x.ID,
                Name = x.NAME,
                Code = x.Code,
                DateSubmitted = x.SUB_DATE
            }).ToList<Model_Table>();
      }
}

现在你可以像这样使用它了:

var result = ctx.table.Query("somethingelse");

【讨论】:

  • OP 正在使用实体框架,因此 ctx.table 的类型为 IQueryable&lt;YourType&gt;
  • 如果使用 ef 表是 DbSet ,它实现了 IEnumerable, IQueryable...
  • 对。但是如果你使用IEnumerable&lt;TEntity&gt;,那么所有的表内容都会被查询到内存中,WhereOrderBy会在内存中执行。我的意思是你的扩展方法应该接受IQueryable&lt;YourType&gt;,这样查询就会发生在数据库端,而不是内存中。
猜你喜欢
  • 2011-10-21
  • 2011-12-31
  • 1970-01-01
  • 1970-01-01
  • 2010-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多