为什么在第二种情况下不执行简单的linq命令?

时间:2014-02-01 22:46:43

标签: c# linq

我的代码中有以下行。

var dates = query.Select(x => EntityFunctions.DiffDays(query.Min(y => y.Date), x.Date));

但是我认为这个命令 query.Min(y => y.Date) 为每个x执行。

所以我想做以下

    System.DateTime varMinDate = query.Min(y => y.Date);
    var dates = query.Select(x => EntityFunctions.DiffDays(varMinDate, x.Date))

我模型的字段日期类型为System.DateTime.

但是,如果我以第二种方式更改它,我会得到一个例外

An exception of type 'System.NotSupportedException' occurred in System.Data.Entity.dll but was not handled in user code

修改

上面提到的查询如下

var query = (from b in db.StudentProgressPerDay
                         where b.Student.Equals(InputStudent)
                         orderby b.Date
                         select b);

为什么?我该如何解决它?

1 个答案:

答案 0 :(得分:1)

不,它只执行一次,通过执行query.ToString(),我们可以看到SQL实体框架将要生成。您的查询生成以下SQL

SELECT 
    DATEDIFF (day, [GroupBy1].[A1], [Extent1].[Date]) AS [C1]
    FROM  [dbo].[Foos] AS [Extent1]
    CROSS JOIN  (SELECT 
        MIN([Extent2].[Date]) AS [A1]
        FROM [dbo].[Foos] AS [Extent2] ) AS [GroupBy1]

您可以看到它执行单个查询以获取最小值,然后它将该查询的结果加入到DATEDIFF,在那里它将反复使用该单个结果。


测试程序

class Context : DbContext
{
    public DbSet<Foo> Foo { get; set; }
}

public class Foo
{
    public int FooId { get; set; }
    public DateTime Date { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        using (var context = new Context())
        {
            var query = context.Foo;
            var dates = query.Select(x => EntityFunctions.DiffDays(query.Min(y => y.Date), x.Date));

            var result = dates.ToString();

            Debugger.Break();
        }
   } 
}