【问题标题】:How to write subselect method for linq to entity query?如何编写 linq 到实体查询的子选择方法?
【发布时间】:2015-10-01 15:20:17
【问题描述】:

我有这个 linq to entity 查询:

var query = (
       from x in ctx.Applications
       from t2 in ctx.Calendar
                  .Where(t2 => t2.Date >= SqlFunctions.DateAdd("dd", x.AllTime, x.RegDate) && t2.FreeDay == false)
                  .OrderBy(t2 => t2.Date)
                  .Take(1)
                  .DefaultIfEmpty()
       select(new ApplicationGridView 
       { 
          ...
          HavePartners = x.HavePartners,
          PlanningEndDate = t2.Date
       });

如何编写扩展方法或带有部分选择的方法(用于不同的选择),如下所示:

public IQueryable<Calendar> GetNextDate(DateTime? dateFrom, int? interval)
{
    return ctx.Calendar
           .Where(t2 => t2.Date >= SqlFunctions.DateAdd("dd", interval, dateFrom) && t2.FreeDay == false)
           .OrderBy(t2 => t2.Date)
           .Take(1)
           .DefaultIfEmpty();
}

然后在select中使用:

var query = (
           from x in ctx.Applications
           from t2 in GetNextDate(x.RegDate, x.AllTime)
           select(new ApplicationGridView 
           { 
              ...
              HavePartners = x.HavePartners,
              PlanningEndDate = t2.Date
           });

var result = query.Where(predicate).ToList();

谢谢

【问题讨论】:

  • 我不确定我是否理解您的问题,但我会尝试;子选择通常是第一次选择完成后的选择。您可以在 ToList() 之前对“var 结果”执行此操作...?如果我的答案离我很远,也许重新写下问题并使其更清楚将是一个好主意...
  • 为什么您的决定(GetNextDate 方法)不起作用? (当然,除非您必须将“ctx”作为参数传递)。
  • 在这个例子中我得到了异常。我也尝试通过 ctx,为 ctx 创建扩展,也为日历实体创建扩展,但始终执行返回错误:EntityFramework.SqlServer.dll 但未在用户代码中处理附加信息:LINQ to Entities 无法识别方法'System.Linq。 IQueryable1[Models.Calendar] GetNextDate(System.Nullable1[System.DateTime], System.Nullable`1[System.Int32])' 方法,并且该方法不能翻译成存储表达式。

标签: c# linq-to-entities extension-methods


【解决方案1】:

我认为@Bjørn 的建议是合适的。但是,如果您不希望对数据库进行额外查询,请检查以下决定。

首先介绍类

    private class MyJoin<T> {
        public T A { get; set; }
        public Calendar B { get; set; }
    }

第二,写一个方法

    private IQueryable<MyJoin<T>> Prepare<T>(IQueryable<MyJoin<T>> myJoin, System.Linq.Expressions.Expression<Func<MyJoin<T>, bool>> clause) {
        return myJoin
            .Where(clause)
            .OrderBy(x=> x.B.Date)
            .Take(1)
            .DefaultIfEmpty();
    }

三、如下使用

        var query = Prepare((from x1 in ctx.Applications
           from x2 in ctx.Calendar
           select(new MyJoin {
               A = x1,
               B = x2,
           })), x => x.B.Date >= SqlFunctions.DateAdd("dd", x.A.AllTime, x.A.RegDate) && x.B.FreeDay == false)
           .Select(x => new { 
              HavePartners = x.A.HavePartners,
              PlanningEndDate = x.B.Date
           });
        var result = query.Where(x => true /* Your condition */).ToList();

最后,您可以将Prepare 方法重写为扩展方法,以获得更简单的语法。

这是否简化了您的任务?请注意,我使用了其他类,因此更正了任何明显的语法或输入错误。

更新。我已经更新了将“where”子句移至方法签名的答案。

【讨论】:

    猜你喜欢
    • 2022-01-08
    • 2015-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-23
    • 1970-01-01
    相关资源
    最近更新 更多