我正在使用EF 4.0和POCO开发一个小应用程序。
在测试我的应用程序时,我开始关注数据访问层的性能。所以我在尝试检索记录时解雇了SQL Profiler:
ctx.Orders.Include("OrderItems").FirstOrDefault<Order>(c => c.OrderID == id);
EF发出一条SQL语句,该语句将从服务器上的Orders表中检索所有记录,并因此返回DAL,此时L2E将选择满足条件的一个并返回它。
可以改变这种行为。
谢谢!
禅
答案 0 :(得分:9)
请试试这个:
ctx.Orders.Include("OrderItems").Where(c => c.OrderID == id).FirstOrDefault();
顺便说一下,您不需要查看SQL事件探查器以查看生成的SQL,您可以通过编写代码在代码内部执行以下操作:
IQueryable<Order> query = ctx.Orders.Include("OrderItems")
.Where(c => c.OrderID == id);
string sql = ((ObjectQuery<Order>)query).ToTraceString();
修改强>
问:如果我们有像 FindOrders 这样的函数,我们需要将谓词传递给这个函数怎么办?
答:代码应如下所示:
public List<Order> FindOrders(Expression<Func<Order, bool>> predicate) {
using (DBContext ctx = new DBContext()) {
return ctx.Orders.Include("OrderItems").Where(predicate).ToList<Order>();
}
}
//Calling the function:
var order = FindOrders(c => c.OrderID == id)[0];
这一次,如果您检查SQL事件探查器,您将看到SQL中有一个where子句已提交给SQL Server。
的说明:强>
这种“怪异行为”的原因在于,当你编写Where(c =&gt; c.OrderID == id)时,C#编译器将你的lambda表达式转换为Expression&lt; Func&lt; TSource,int,bool&gt;&gt;而不是Func&lt; TSource,int,bool&gt;。
MSDN Documentation for Queryable.Where也证实了这一点:
public static IQueryable<TSource> Where<TSource>(
this IQueryable<TSource> source,
Expression<Func<TSource, int, bool>> predicate
)
public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, int, bool> predicate
)
using System.Linq.Expressions;