linq to sql select和where的区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linq to sql select和where的区别相关的知识,希望对你有一定的参考价值。

就是 linq对象.表名.where/select<>() 这两个分别是用作什么情况下的

这两个关键字都对查询结果有作用,但where子句是条件判定,起到筛选作用。select子句产生结果序列的类型,决定了查询变量的类型。在最简单情况下,select子句就指定局部变量,使得返回序列包含了与数据源一样的类型。然而,select子句也提供将源数据变换为新类型。另外一个很重要的功能是,查询表达式必须用select子句或group子句结尾。 参考技术A select 是映射 将序列中的每个元素投影到新表中。
http://msdn.microsoft.com/zh-cn/library/system.linq.enumerable.select.aspx
就像你sql中 select * 和select table.字段名一样 一个是取所有 一个是取一列字段
select能映射出你想要的数据

where 是选择 基于谓词筛选值序列。
http://msdn.microsoft.com/zh-cn/library/bb534803.aspx
同sql中的where

理解LINQ to SQL中的.AsEnumerable()

给出以下LINQ to SQL查询:

var test = from i in Imports
           where i.IsActive
           select i;

解释的SQL语句是:

SELECT [t0].[id] AS [Id] .... FROM [Imports] AS [t0] WHERE [t0].[isActive] = 1

假设我想在select中执行一些无法转换为SQL的操作。我的理解是,传统的方法是做AsEnumerable(),从而将其转换为可行的对象。

鉴于此更新的代码:

var test = from i in Imports.AsEnumerable()
           where i.IsActive
           select new 
           { 
               // Make some method call 
           };

并更新了SQL:

SELECT [t0].[id] AS [Id] ... FROM [Imports] AS [t0] 

注意执行的SQL语句中缺少where子句。

这是否意味着整个“Imports”表被缓存到内存中?如果表包含大量记录,这会导致性能下降吗?

帮助我了解幕后实际发生的事情。

答案

AsEnumerable的原因是

当序列实现IEnumerable(T)但也有一组不同的公共查询方法时,AsEnumerable(TSource)(IEnumerable(TSource))可用于在查询实现之间进行选择

因此,当您之前调用Where方法时,您从Where调用了另一种IEnumerable.Where方法。 Where声明是为了LINQ转换为SQL,新的WhereIEnumerable,它采用IEnumerable,枚举它并产生匹配的项目。这解释了为什么您看到生成的不同SQL。在您的第二版代码中应用Where扩展之前,将从数据库中完整地获取该表。这可能会造成严重的瓶颈,因为整个表必须在内存中,或者更糟糕的是整个表必须在服务器之间传输。允许SQL服务器执行Where并执行它最擅长的操作。

另一答案

在枚举枚举的位置,将查询数据库,并检索整个结果集。

零件和零件解决方案可以是方式。考虑

var res = (
    from result in SomeSource
    where DatabaseConvertableCriterion(result)
    && NonDatabaseConvertableCriterion(result)
    select new {result.A, result.B}
);

我们还要说NonDatabaseConvertableCriterion要求结果中的字段C.因为NonDatabaseConvertableCriterion就像它的名字所暗示的那样,所以必须以枚举的形式执行。但是,请考虑:

var partWay =
(
    from result in SomeSource
    where DatabaseConvertableCriterion(result)
    select new {result.A, result.B, result.C}
);
var res =
(
    from result in partWay.AsEnumerable()
    where NonDatabaseConvertableCriterion select new {result.A, result.B}
);

在这种情况下,当枚举,查询或以其他方式使用res时,尽可能多的工作将传递给数据库,该数据库将返回足以继续该作业的数据库。假设确实无法重写以便可以将所有工作发送到数据库,这可能是一个合适的折衷方案。

另一答案

AsEnumerable有三种实现方式。

DataTableExtensions.AsEnumerable

扩展DataTable以使其具有IEnumerable界面,因此您可以使用Linq对抗DataTable

Enumerable.AsEnumerable<TSource>ParallelEnumerable.AsEnumerable<TSource>

除了将源的编译时类型从实现AsEnumerable<TSource>(IEnumerable<TSource>)的类型更改为IEnumerable<T>本身之外,IEnumerable<T>方法没有任何效果。

当序列实现AsEnumerable<TSource>(IEnumerable<TSource>)但也有一组不同的公共查询方法可用时,IEnumerable<T>可用于在查询实现之间进行选择。例如,给定一个实现Table的通用类IEnumerable<T>并拥有自己的方法,如WhereSelectSelectMany,调用Where将调用Where的公共Table方法。表示数据库表的Table类型可以具有Where方法,该方法将谓词参数作为表达式树并将树转换为SQL以进行远程执行。如果不需要远程执行,例如因为谓词调用本地方法,则可以使用AsEnumerable<TSource>方法隐藏自定义方法,而是使标准查询运算符可用。

换一种说法。

如果我有

IQueryable<X> sequence = ...;

来自LinqProvider,比如Entity Framework,我做的,

sequence.Where(x => SomeUnusualPredicate(x));

该查询将在服务器上编写并运行。这将在运行时失败,因为EntityFramework不知道如何将SomeUnusualPredicate转换为SQL。

如果我希望用Linq对象运行语句,我会这样做,

sequence.AsEnumerable().Where(x => SomeUnusualPredicate(x));

现在服务器将返回所有数据,并且将使用从Linq到Objects的Enumerable.Where而不是Query Provider的实现。

实体框架不知道如何解释SomeUnusualPredicate无关紧要,我的函数将直接使用。 (但是,这可能是一种低效的方法,因为所有行都将从服务器返回。)

另一答案

我相信AsEnumerable只是告诉编译器使用哪些扩展方法(在这种情况下是为IEnumerable而不是为IQueryable定义的扩展方法)。查询的执行仍然延迟,直到您调用ToArray或枚举它为止。

以上是关于linq to sql select和where的区别的主要内容,如果未能解决你的问题,请参考以下文章

Linq to Entities基础之需要熟知14个linq关键字(from,where,select,group,let,on,by...)

理解LINQ to SQL中的.AsEnumerable()

Linq to SQL 的增删改查操作

Linq To Sql Contains 参数数量最大不能超过 2100 怎么解决?

了解 LINQ to SQL 中的 .AsEnumerable()

LINQ to SQL语句之Where