2015-07-13 58 views
1

我有这样的LINQ到实体查询:如何将linq的subselect方法写入实体查询?

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 
     }); 

如何写有一部分选择(使用在diferrent选择)扩展方法或方法,像这样:

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(); 
} 

然后用在选择:

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(); 

感谢

+1

我不知道我理解你的问题,但我会尝试;子选择通常是在第一次选择完成后的选择。你可以在“var结果”上做到这一点,在你的ToList()之前......?如果我的答案很遥远,也许重新写下这个问题,并使其更清晰将是一个好主意... –

+0

为什么您的决定(GetNextDate方法)不起作用? (当然,除了你必须通过“ctx”作为参数)。 – Hoborg

+0

在这个例子中,我得到例外。另外我尝试通过ctx,为ctx创建扩展,也为Calendar实体创建扩展,但始终执行返回错误:EntityFramework.SqlServer.dll,但未在用户代码中处理 附加信息:LINQ to Entities不能识别方法System。 Linq.IQueryable'1 [Models.Calendar] GetNextDate(System.Nullable'1 [System.DateTime],System.Nullable'1 [System.Int32])''方法,并且此方法不能转换为存储表达式。 –

回答

0

我认为@Bjorn的建议是适当的。但是,如果您不想向数据库追加一个查询,请检查以下决定。

首先,引进一流

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”条款移到了方法的签名中。

+0

谢谢,很好的答案,我尝试测试它 –