【发布时间】:2016-10-01 16:15:29
【问题描述】:
我正在使用通用存储库,如下所示:
itemsList = (from myrow in UoW.FileRepository.Get()
select new FileModel()
{record_id = myrow.type_id,
descr = myrow.descr}).ToList();});
这是 Get 方法:
public virtual IEnumerable<TEntity> Get()
{
// _aQuery = _theDbContext.Set<TEntity>();
IEnumerable<TEntity> query = _aQuery;
return query;
}
如果我想创建一个类似的查询来搜索特定字段中的特定字符串,我将如何实现一个通用的 linq lambda 表达式?在我的视图模型中,我想这样称呼:
from myrow in UoW.FileRepository.Srch(nameofFieldToSearch, searchString).
查询看起来像这样?
public IEnumerable<TEntity> Srch(Expression<Func<TEntity, bool>> expression)
{
IEnumerable<TEntity> srchList = _aQuery.ToList();
return srchList.Where(????);
}
感谢您的建议。
编辑----------- 我在通用存储库类中有所有查询,例如 Get 和 Srch,现在只需要知道如何在存储库类中声明查询以及如何使用我的视图模型中的搜索字符串调用它。我不确定是否就何时/何时实现和编译达成共识?我看到另一个讨论http://www.fascinatedwithsoftware.com/blog/post/2012/01/10/More-on-Expression-vs-Func-with-Entity-Framework.aspx,我在下面引用它来询问这是否与这里建议的方法相同?再次感谢。
“分析器告诉我们,LoadMyEntities 被调用了很多很多次,它占用了我们大部分 CPU 时间。下面的简单更改解决了这个问题。你能猜出原因吗?”
public IEnumerable<MyEntity> LoadMyEntities(Func<MyEntity, bool> predicate)
{return Context.MyEntities.Where(predicate);}
“参数现在是一个 Func 而不是一个表达式>。这有所不同的原因是一个表达式形式的谓词被传递给 SQL 服务器,但是一个作为 Func 传递的谓词是不是。通常情况下,您希望 SQL Server 为您做尽可能多的事情,而 Expression 将是正确的选择,但在这种情况下,我们希望在上下文中预加载整个表——即正是 Func 的作用。
- Where 扩展方法有两种风格。一个扩展 IQueryable 并采用 Expression 参数。另一个扩展 IEnumerable 并采用 Func。
- 因为“谓词”现在是一个 Func,所以使用了扩展 IEnumerable 的 Where。
- Entity Framework 用于构建 SQL 查询的流畅接口基于 IQueryables,而不是 IEnumerables。因此,流畅度在 Where 之前停止。传递给实体框架的语句部分只是 Context.MyEntities。
- 因此,Context.MyEntities 会将整个表返回到上下文。
- 现在使用谓词过滤整个表,并返回我们真正想要的值。
- 下次调用该方法时,实体框架意识到我们想要的记录已经在上下文中。 (在我的例子中,我们通过主键进行查询,而 EF 显然足够聪明,可以知道如果上下文中存在具有该 ID 的记录,它不会在数据库中找到额外的此类记录。)因为我们不不要使用 SQL Server,我们可以节省大量时间。显然,有时您不希望这样做,但在我们的情况下,这正是我们想要的。表比较小,同一个上下文被查询了几百次。
在原始版本中,谓词是一个表达式,因此编译器使用了扩展 IQueryable 的 Where。谓词因此被传递给 SQL Server,它尽职尽责地将一行返回给上下文。下次我们调用 LoadMyEntities 时,Entity Framework 不得不再次调用 SQL Server。”
【问题讨论】:
-
查看动态 LINQ。
标签: c# linq lambda expression