【问题标题】:.NetCore C# - Can LINQ Query operators be seperated by logic?.Net Core C# - LINQ 查询运算符可以按逻辑分隔吗?
【发布时间】:2018-03-30 22:09:55
【问题描述】:

假设我有六个LINQ queries。每个查询都包含上一个查询使用的运算符,并在链中再添加一个运算符:

Foo = await
(
    _context.Foo
        .Where(f => (Convert.ToDateTime(f.date1) - today).TotalDays < 31)
 )
 .ToListAsync(); 

Foo = await
(
    _context.Foo
        .Where(f => (Convert.ToDateTime(f.date1) - today).TotalDays < 31)
        .Where(f => f.recordid == x)
 )
 .ToListAsync(); 

Foo = await
(
    _context.Foo
        .Where(f => (Convert.ToDateTime(f.date1) - today).TotalDays < 31)
        .Where(f => f.recordid == x)
        .Where(f => !StatusExceptionList.Contains(r.Status))
 )
 .ToListAsync(); 

Foo = await
(
    _context.Foo
        .Where(f => (Convert.ToDateTime(f.date1) - today).TotalDays < 31)
        .Where(f => f.recordid == x)
        .Where(f => !StatusExceptionList.Contains(r.Status))
        .OrderBy(f => f.date1)
 )
 .ToListAsync(); 

Foo = await
(
    _context.Foo
        .Where(f => (Convert.ToDateTime(f.date1) - today).TotalDays < 31)
        .Where(f => f.recordid == x)
        .Where(f => !StatusExceptionList.Contains(r.Status))
        .OrderBy(f => f.date1)
        .ThenBy(f => f.date2)
)
.ToListAsync(); 

Foo = await
(
    _context.Foo
        .Where(f => (Convert.ToDateTime(f.date1) - today).TotalDays < 31)
        .Where(f => f.recordid == x)
        .Where(f => !StatusExceptionList.Contains(r.Status))
        .OrderBy(f => f.date1)
        .ThenBy(f => f.date2)
        .ThenBy(f => f.recordid)
)
.ToListAsync(); 

我想将其压缩为一个查询,并在不同的 linq 运算符之间编织逻辑,正如此伪代码所示,但这根本不起作用。我用谷歌搜索了一下,不知道下一步该尝试什么:

Foo = await
(
    _context.Foo
        .Where(f => (Convert.ToDateTime(f.date1) - today).TotalDays < 31)
        if (some logic)
        {
            .Where(f => f.recordid == x)
        }
        if (some different logic)
        {           
            .Where(f => !StatusExceptionList.Contains(r.Status))
        }
        if (some different logic)
        {
            .OrderBy(f => f.date1)
        }
        if (some different logic)
        {
            .ThenBy(f => f.date2)
        }
        if (some different logic)
        {
            .ThenBy(f => f.recordid)
        }
)
.ToListAsync(); 

谁能指出我正确的方向或告诉我我是否试图以错误的方式解决这个问题?非常感谢!!!

【问题讨论】:

    标签: c# linq asp.net-core


    【解决方案1】:

    只需将查询存储在单独的变量中:

    IQueryable<Foo> query = _context.Foo
        .Where(f => (Convert.ToDateTime(f.date1) - today).TotalDays < 31);
    

    然后附加您的支票:

    if (someCondition) {
        query = query.Where(f.recordid == x);
    }
    

    等等。最后 - 运行查询:

    Foo = await query.ToListAsync();
    

    使用OrderByThenBy - 检查查询是否已经是IOrderedQueryable

    if (someCondition) {
        var ordered = query as IOrderedQueryable<Foo>;
        if (ordered != null)
            query = ordered.ThenBy(x => x.field);
        else 
            query = query.OrderBy(x => x.field);
    }
    

    【讨论】:

    • 这个答案让我完全明白该怎么做。
    【解决方案2】:

    您可以构造查询,然后等待其结果:

    IQueryable<Foo> query = _context.Foo
        .Where(f => (Convert.ToDateTime(f.date1) - today).TotalDays < 31);
    if (some logic) {
        query = query.Where(f => f.recordid == x);
    }
    if (some different logic) { 
        query = query.Where(f => !StatusExceptionList.Contains(r.Status));
    }
    if (some ordering logic 1) {
        query = query.OrderBy(f => f.date1);
    }
    if (some ordering logic 2) {
        query = ((IOrderedQueryable<Foo>)query).ThenBy(f => f.date2);
    }
    if (some ordering logic 3) {
        query = ((IOrderedQueryable<Foo>)query).ThenBy(f => f.recordid);
    }
    

    重要的是“一些排序逻辑1”弱于“一些排序逻辑2”和“一些排序逻辑3”,否则转换不会成功。

    另一种方法是创建一个Where 条件:

    Foo = await
    (
        _context.Foo
            .Where(f => (Convert.ToDateTime(f.date1) - today).TotalDays < 31
            && (conditionFor2 && f.recordid == x)
            && (conditionFor3 && !StatusExceptionList.Contains(r.Status))
    ).ToListAsync(); 
    

    【讨论】:

      【解决方案3】:

      你可以分配一个变量:

      var query = _context.Foo
          .Where(f => (Convert.ToDateTime(f.date1) - today).TotalDays < 31);
      
      if (something)
      {
          query = query.Where(f => !StatusExceptionList.Contains(r.Status));
      }
      

      等等。

      最后:

      var result = await query.ToListAsync();
      

      【讨论】:

      • 感谢您的快速回复。我正在使用 await 和 .ToListAsync() 关键字,我认为它们会阻止我使用匿名对象。添加 var 关键字会给我一条消息,说明“名称 var 在当前上下文中不存在”,并且使用 .ToListAsync 方法也会给出相同的消息。
      • @ogg130 您在错误的范围内使用了 var。将您的逻辑移动到 List Filter() 之类的单独方法,并从我给出的示例开始。
      • 我明白了!谢谢,感谢您的耐心等待!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-25
      • 1970-01-01
      • 2021-01-24
      • 2015-04-27
      • 2014-07-07
      • 1970-01-01
      相关资源
      最近更新 更多