Jac*_*cob 15 linq linq-to-entities entity-framework linq-to-sql
我正在创建一个带有服务层(WCF网站)和Silverlight 4客户端的应用程序.RIA服务不是一种选择,因此我们创建了来回传递的中间类.出于这个问题的目的,让我们假设我来回传递美味Food
物体.
public class FoodData
{
public int Id { get; set; }
public string Name { get; set; }
public Tastyness TastyLevel { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
EF模型本质上是同一个类,一个包含三个基本字段的表(Tastyness是一个与我们的enum Tastyness相对应的int).
在进行实体框架查询时,我发现自己经常使用这种语句:
public List<FoodData> GetDeliciousFoods()
{
var deliciousFoods = entities.Foods
.Where(f => f.Tastyness == (int)Tastyness.Delicious)
.ToList() // Necessary? And if so, best performance with List, Array, other?
.Select(dFood => dFood.ToFoodData())
.ToList();
return deliciousFoods;
}
Run Code Online (Sandbox Code Playgroud)
没有.ToList()调用,我得到一个关于LINQ无法将自定义方法转换为查询等价物的异常,我理解.
我的问题是在.Select(... )之前调用.ToList(),使用自定义扩展将我们的对象转换为Food对象的POCO版本.
有没有更好的模式在这里做,或者甚至可能是更好的替代.ToList()可能更高效,因为我并不真正需要List <..>结果的功能.
Cra*_*ntz 12
使用ToList
或问题AsEnumerable
是您实现整个实体并支付修复费用.如果你想拥有最好的SQL,它只返回所需的字段,那么你应该直接投影而不是使用.ToFoodData()
:
var deliciousFoods = entities.Foods
.Where(f => f.Tastyness == (int)Tastyness.Delicious)
.Select(dFood => new FoodData
{
Id = dFood.Id,
Name = dFood.Name,
TastyLevel = (Tastyness)dFood.Tastyness
});
Run Code Online (Sandbox Code Playgroud)
演员到枚举可能是一个问题.如果是这样,请浏览匿名类型:
var deliciousFoods = entities.Foods
.Where(f => f.Tastyness == (int)Tastyness.Delicious)
.Select(dFood => new FoodData
{
Id = dFood.Id,
Name = dFood.Name,
TastyLevel = dFood.Tastyness
})
.AsEnumerable()
.Select(dFood => new FoodData
{
Id = dFood.Id,
Name = dFood.Name,
TastyLevel = (Tastyness)dFood.TastyLevel
});
Run Code Online (Sandbox Code Playgroud)
如果检查生成的SQL,您会发现它更简单,并且您不需要支付将对象修复到ObjectContext的成本.
使用AsEnumerable()
打开查询到一个普通的旧LINQ到对象的查询,而无需创建一个不需要名单
var deliciousFoods = entities.Foods
.Where(f => f.Tastyness == (int)Tastyness.Delicious)
.AsEnumerable()
.Select(dFood => dFood.ToFoodData())
.ToList();
Run Code Online (Sandbox Code Playgroud)
编辑:请参阅http://www.hookedonlinq.com/AsEnumerableOperator.ashx