2015-07-10 52 views
0

我试图开始使用EF6作为项目。我的数据库已经充满了数百万条记录。其中EF6在SQL或客户端执行where子句

我无法找到正确的解释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; 
} 

回答

1

在所有3个的情况下,滤波会发生在数据库端,滤波(或WHERE子句)将不会发生在客户端。

如果你想验证这是否是真实的,尤其是对你最后的2个选项,添加一些记录,这样就可以看到生成的SQL:,

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

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

1

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

直到迭代遍历结果(在上面的示例中,这是您调用.ToList()时的结果),它实际上不会从数据库中检索任何数据。

EF6只会在客户端上运行的过滤器,如果你叫一样的东西:

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

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

1

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

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

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

如果您绝对需要使用EF无法处理的某些代码,则可以将代码分解为多个段 - 尽可能使用AsEnumerable()方法通过可转换为SQL的代码进行过滤“关闭”EF表达式,并使用Linq to Objects进行剩余的过滤或转换。