背景
ArticleService
是一个类,为前端层提供方法,方便与后端业务。
它的两个基本职责是转换 ViewModel(ArticleViewModel
)到适当的模型(Article
)在保存数据时,反之,在获取数据时将模型转换为 ViewModel...如此频繁,以至于我创建了一个构建 ViewModel 对象的私有方法:
private ArticleViewModel BuildViewModel(Article a)
{
return new ArticleViewModel { Title = a.Title /* all properties */ }
}
一路前行,ArticleService
提供了一种从数据存储中获取所有文章的方法,并将它们作为 ViewModel 返回:public IEnumerable<ArticleViewModel> All()
调用类像这样使用它:var articleViewModels = _articleService.All();
很简单,对吧?
Problem:
我最初写的All()
懒洋洋地带着经典foreach
loop:
private IEnumerable<ArticleViewModel> All()
{
var viewModels = new List<ArticleViewModel>();
foreach (var article in _db.Articles)
viewModels.Add(BuildViewModel(article));
return viewModels;
}
效果很好 -articleViewModels
是所有视图模型的实例化列表。
接下来,为了性能和美观,我使用 ReSharper 将此循环转换为 LINQ 语句,然后将赋值语句与 return 语句结合起来。结果:
private IEnumerable<ArticleViewModel> All()
{
return _db.Articles.Select(article => BuildViewModel(article)).ToList();
}
我调试了 LINQ 语句,野兽苏醒了:
LINQ to Entities 无法识别方法“ArticleViewModel”
BuildViewModel(Article)' 并且此方法无法转换为存储表达式。
问题 - 为什么这个 LINQ 语句会破坏我的代码?
注意:回到 LINQ 语句的显式声明、赋值、返回,因此我几乎可以肯定这与 lambda 逻辑有关。