我正在尝试将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;
}
答案 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进行剩余的过滤或转换。