2012-11-21 35 views
0

我想给继承类提供一个where子句给我的查询的机会。这可能吗?IQueryable where子句被继承类重写

protected IQueryable<EntityResult> GetEntities(ETBDataContext pContext) 
    { 
     return from e in pContext.Entities 
       where e.StatusCode == "Published" 

       //is there a way to add a dynamic where clause here? 
       //I would like to ask the inherited class for it's input: 

       && e.OtherColumn == "OtherValue" // <-- like GetWhere(e)? 

       //without having to select the column 

       orderby e.PublishDate descending 

       select new EntityResult 
       { 
        Name = e.Name, 
        Link = e.Link 
       }; 
    } 

先谢谢了!!!!!!!!!!

回答

0

您可以定义可以申请额外的虚拟方法,其中条件:

protected IQueryable<EntityResult> GetEntities(ETBDataContext pContext) 
{ 
    IQueryable<Entity> query = pContext.Entities 
     .Where(e => e.StatusCode == "Published"); 

    query = ApplyWhereClause(query); 

    return from e in query 
      orderby e.PublishDate descending 
      select new EntityResult 
       { 
        Name = e.Name, 
        Link = e.Link 
       }; 
    } 

protected virtual IQueryable<Entity> ApplyWhereClause(IQueryable<Entity> entities) 
{ 

} 

在你的派生类,你会那么做:

protected override IQueryable<Entity> ApplyWhereClause(IQueryable<Entity> entities) 
{ 
    return entities.Where(/* insert your extra where clause here */); 
} 
+0

非常感谢。此代码第一次编译和工作。只有一个问题:所有这些仍然是在数据源上执行还是将其加载到内存中然后进行过滤? –

+0

有趣的是,我从来没有想过在第一种方法中分裂它。 –

+0

只要您使用'IQueryable',就不会在数据库中执行任何操作。只有在调用.ToList()或类似的函数时,或者在结果上开始执行foreach才会实际执行针对数据库的查询。 – jeroenh

3

既然你返回一个IQueryable当使用资源的查询才会执行。所以只要它保持IQueryable,它将保留查询。

有了这些知识,你可以简单地套用在你的函数返回的IQueryable

像这样的地方:

myObject.GetEntities(myContextObject).Where(x => x.id == 5); 

由于OtherCOlumn心不是有你所说的,你可以更改默认查询:

protected IQueryable<EntityResult> GetEntities(ETBDataContext pContext) 
{ 
    return (from e in pContext.Entities 
      where e.StatusCode == "Published" 

      //is there a way to add a dynamic where clause here? 
      //I would like to ask the inherited class for it's input: 

      && e.OtherColumn == "OtherValue" // <-- like GetWhere(e)? 

      //without having to select the column 

      orderby e.PublishDate descending 

      select e).FirstOrDefault(); 
} 

然后在你的扩展位置做选择。由于它保持查询只要返回类型保持IQueryable这不会让它变得更慢

+0

谢谢你,但得到的查询不包括OtherColumn属性可供选择。所以当我在后面应用where子句时,就像.Where(er => er.OhterColumn)那样,OtherColumn不存在。 –

+0

我编辑了我的答案 – middelpat

0

我不知道如何写Linq表示法,因为我总是喜欢使用Linq扩展方法,但它会看起来是这样的:

protected IQueryable<EntityResult> GetEntities(ETBDataContext pContext) 
{ 
    var q = pContext.Entities 
     .Where(e => e.StatusCode == "Published"); 
    q = q.AddWhereCondition(q) 
     .OrderByDescending(e => e.PublishDate) 
     .Select(e => new EntityResult 
      { 
       Name = e.Name, 
       Link = e.Link 
      }); 
} 

protected virtual IQueryable<Entity> AddWhereCondition(IQueryable<Entity> query) 
{ 
    return query.Where(e => e.OtherColumn == "OtherValue"); 
} 

,或者通过提取其中()条件的LINQ表达式:

protected IQueryable<EntityResult> GetEntities(ETBDataContext pContext) 
{ 
    var q = pContext.Entities 
     .Where(e => e.StatusCode == "Published") 
     .Where(e => GetWhereCondition(e)) 
     .OrderByDescending(e => e.PublishDate) 
     .Select(e => new EntityResult 
      { 
       Name = e.Name, 
       Link = e.Link 
      }); 
} 

protected virtual Expression<Func<Entity, bool>> GetWhereCondition(Entity e) 
{ 
    return e => e.OtherColumn == "OtherValue"; 
}