我的信念一直是,如果BigDataSet
是一个实体并且您指定var someThing = Context.BigDataSet.Single(x => x.Name.Trim().ToUpper.Equals(someName.Trim().ToUpper()));
,那么EF会将您的lambda表达式转换为查询,例如
SELECT * FROM big_data_set WHERE name = (someName)
但是在考虑之后,除了将Context.BigDataSet
的结果保留在内存中并然后执行搜索之外,我看不到它的工作方式。
EF DbSet
lambda表达式是否会变成SQL,或者它是否都是在事后应用的?
编辑:如果他们确实变成了SQL,那么EF
如何“看到”在获取名称后会发生的所有事情?如果我致电instance.MethodA().MethodB()
,这通常意味着方法A
和B
是按顺序执行的吗?
答案 0 :(得分:4)
实体框架在您迭代查询之前不会访问数据库,实质上是它返回的IQueryable,然后在您进行迭代时将其转换为SQL查询。
var query = context.Employees; // Returns IQueryable<Employee>
var employees = context.Employees.ToList(); // Returns List<Employee> (Hits the database)
如果您需要全面的解释,可以谷歌“实体框架延期执行”。
答案 1 :(得分:3)
EF provider implementations.获取表达式树而不是lambdas。
More about expressions in EF
在更多地考虑了你的问题后,我的猜测是你没有意识到使用的表达式。
Expression<Function<t,bool>> predicate
与Func<t,bool> predicate
之间的差异。很重要。提供者将无法使用func。它需要一个表达式树。
LINQ的一个子集可以在基于Linq to entities标准的表达式中使用。supported queries
在调试器中尝试并查看Expression<Func<t,bool>>
类型变量的内容。
您可以很好地了解lambda如何转换为表达式,并且数据库提供程序使用此表达式转换为SQL。
答案 2 :(得分:2)
除非您在存储过程函数映射上执行lambda操作,否则它们将变为SQL。 您可以使用SQL事件探查器(或EF分析器)自行查看,并查看运行查询时生成的SQL。
答案 3 :(得分:2)
直接在实体上调用它们时会被翻译成SQL。
如果要在本地缓存结果,以便在实体的每个查询中都没有访问数据库,则可以立即执行,例如:通过ToList()
然后对这些缓存的值运行多个查询。显然,这会直接击中数据库,但只是一次。
与LINQ查询一样,在您开始迭代生成的IEnumerable之前,工作不会发生(即没有命中数据库)。
通过查看从查询中生成的SQL,您可以更好地理解问题的第二部分,例如通过尝试:
var query = Context.BigDataSet.Single(x => x.Name.Trim().ToUpper.Equals(someName.Trim().ToUpper()));
var objectQuery=query as System.Data.Objects.ObjectQuery;
Console.WriteLine(objectQuery.ToTraceString());