我有以下方法:
private IEnumerable<CTNTransactionsView> RetrieveCTNTransactionsNotInTLS() {
IQueryable<int> talismanIdCollection = this._cc.TLSTransactionView.Select(x => x.kSECSYSTrans);
return this._cc.CTNTransactionView
.Where(x => !talismanIdCollection.Contains(x.kSECSYSTrans));
}
public IEnumerable<CTNTransactionsView> RetrieveCTNTransactionsNotInTLSPast24Hours() {
DateTime previousDate = DateTime.Now.Date.AddDays(-1.0);
return this.RetrieveCTNTransactionsNotInTLS()
.Where(x => x.dSECSYSTimeStamp >= previousDate);
}
public IEnumerable<CTNTransactionsView> RetrieveCTNTransactionsNotInTLSPast24HoursVersionTwo() {
DateTime previousDate = DateTime.Now.Date.AddDays(-1.0);
IQueryable<int> talismanIdCollection = this._cc.TLSTransactionView
.Select(x => x.kSECSYSTrans);
return this._cc.CTNTransactionView
.Where(x => !talismanIdCollection.Contains(x.kSECSYSTrans))
.Where(x=> x.dSECSYSTimeStamp >= previousDate);
}
由于某种原因,Entity Framework 6生成的SQL输出与结果不匹配。
RetrieveCTNTransactionsNotInTLSPast24HoursVersionTwo()方法将正确地提供具有以下内容的SQL输出语句:
select ...... from ... where ... AND ([Extent1].[dSECSYSTimeStamp] >= @p__linq__0)}
当我查看SQL语句输出时,另一个没有dSECSYSTimeStamp的过滤器。
我比较的方法是RetrieveCTNTransactionsNotInTLSPast24Hours()和RetrieveCTNTransactionsNotInTLSPast24HoursVersionTwo()。
我已经使用VS比较了SQL,并在上下文中将Debug.Writeline()附加到Database.Log。
从调试和查看SQL输出,似乎包含日期过滤器,而另一个没有,但它们都提供了正确的结果。
我尝试使用以下内容查看SQL(通过断点和查看输出):
System.Diagnostics.Debug.WriteLine("Running first method");
var result = this.repo.RetrieveCTNTransactionsNotInTLSPast24Hours();
var count = result.Count();
System.Diagnostics.Debug.WriteLine("Running Second method");
var resultTwo = this.repo.RetrieveCTNTransactionsNotInTLSPast24HoursVersionTwo();
var count2 = resultTwo.Count();
我正在使用EF 6.0。
注意:结果与两者完全相同并输出相同结果相同。但是,我很好奇并且想了解为什么SQL Generated不一样?
答案 0 :(得分:1)
问题是你从你的方法返回一个IEnumerable。如果执行此操作,则强制SQL运行查询(未过滤),然后使用C#运行第二个查询。更改内部查询以返回IQueryable。这将允许将未执行的表达式树传递给第二个查询,然后在运行它时对其进行评估。
即
private IQueryable<CTNTransactionsView> RetrieveCTNTransactionsNotInTLS()
然后你应该得到相同的SQL。
答案 1 :(得分:0)
我认为,你只是定义一个查询表达式,但不能立即使用它,在这个时候,我会在 Linq 表达式的结尾添加.ToList()
,但是你必须改变方法的在此操作之前将类型返回到类似List<kSECSYSTrans>
的正确类型。我很少使用IEnumerable
类型。