方法在EF6中链接不输出正确的SQL

时间:2016-04-07 00:40:53

标签: c# entity-framework visual-studio visual-studio-2015 entity-framework-6

我有以下方法:

        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不一样?

2 个答案:

答案 0 :(得分:1)

问题是你从你的方法返回一个IEnumerable。如果执行此操作,则强制SQL运行查询(未过滤),然后使用C#运行第二个查询。更改内部查询以返回IQueryable。这将允许将未执行的表达式树传递给第二个查询,然后在运行它时对其进行评估。

private IQueryable<CTNTransactionsView> RetrieveCTNTransactionsNotInTLS()

然后你应该得到相同的SQL。

答案 1 :(得分:0)

我认为,你只是定义一个查询表达式,但不能立即使用它,在这个时候,我会在 Linq 表达式的结尾添加.ToList(),但是你必须改变方法的在此操作之前将类型返回到类似List<kSECSYSTrans>的正确类型。我很少使用IEnumerable类型。