EF6在SQL或客户端

时间:2015-07-10 14:56:34

标签: sql-server entity-framework

我正在尝试将EF6用于项目。我的数据库已经填满了数百万条记录。

我找不到正确的解释EF如何将T-SQL发送到SQL Server?我担心我会毫无理由地向用户下载大量数据。

在下面的代码中,我找到了将数据传递给List<>的三种方法,但我不确定在SQL上执行WHERE子句的正确方法。

我不希望用数百万条记录填充客户端,并在客户端查询(过滤)该数据。

using (rgtBaza baza = new rgtBaza())
{
    var t = baza.Database.SqlQuery<CJE_DOC>("select * from cje_doc where datum between @od and @do",new SqlParameter("od", this.dateTimePickerOD.Value.Date )  ,new SqlParameter("do", this.dateTimePickerOD.Value.Date)).ToList();

    var t = baza.CJE_DOC.Where(s => s.DATUM.Value >= this.dateTimePickerOD.Value.Date && s.DATUM.Value <= this.dateTimePickerDO.Value.Date).ToList();

    var query = from b in baza.CJE_DOC
                where b.DATUM >= this.dateTimePickerOD.Value.Date && b.DATUM.Value <= this.dateTimePickerDO.Value.Date
                select b;

    var t = query.ToList();

    this.dataGridViewCJENICI.DataSource = t;
}

3 个答案:

答案 0 :(得分:1)

在所有3种情况下,过滤将在数据库端进行,过滤(或WHERE子句)将不会在客户端进行。

如果要验证这是否属实,尤其是最后两个选项,请添加一些日志记录,以便您可以看到生成的SQL:

baza.Database.Log = s => Console.WriteLine(s);

在这种情况下,由于您已经使用EF,请选择第二个或第三个选项,它们都具有不同的语法。选择你最喜欢的语法。

答案 1 :(得分:1)

在所有这些示例中,EF6将生成包含where子句的SQL查询 - 它不会在客户端上执行where子句。

在迭代结果之前,它实际上不会从数据库中检索任何数据,在上面的例子中,当你调用.ToList()时。

如果您调用类似的内容,EF6将仅在客户端上运行过滤器:

baza.CJE_DOC.ToList().Where(x => x.Field == value)

在这种情况下,它会在您调用ToList()时检索整个表,然后使用客户端Linq查询来过滤where子句中的结果。

答案 2 :(得分:1)

3中的任何一个都将在SQL Server上运行查询。

EF依靠LINQ的延迟执行模型来构建表达式树。一旦你采取导致表达式被枚举的动作(例如调用ToList()ToArray()或任何其他To*()方法),它将表达式树转换为SQL,发送查询到服务器,然后开始返回结果。

其中一个副作用是,当使用查询或lambda语法时,EF不了解如何转换为SQL的表达式将导致异常。

如果您绝对需要使用EF无法处理的某些代码,您可以将代码分成多个部分 - 使用{{转换为SQL的代码尽可能地过滤掉代码。 1}}方法到&#34;关闭&#34; EF表达式,并使用Linq to Objects进行剩余的过滤或转换。