.net LINQ到对象-使用哲学?

.net LINQ到对象-使用哲学?,.net,linq,object,.net,Linq,Object,我开始探索LINQ到对象,但想知道应用程序设计如何最好地适应LINQ到对象 例如。。。。应用程序仅显示女性员工,数据库中的employee表包含男性和女性员工的数据 默认情况下,应用程序构建一个SQL语句,仅从数据库中检索女性员工,并将她们放入一个对象(列表),然后将该对象传递给应用程序进行显示等 为了最大限度地利用LINQ对对象的影响,我假设您首先必须获取员工的所有数据,然后应用LINQ过滤对象,只显示女性员工。这样做的好处是,您可以继续查询员工,而无需再次触摸数据库 这是一个基本的例子,但我

我开始探索LINQ到对象,但想知道应用程序设计如何最好地适应LINQ到对象

例如。。。。应用程序仅显示女性员工,数据库中的employee表包含男性和女性员工的数据

默认情况下,应用程序构建一个SQL语句,仅从数据库中检索女性员工,并将她们放入一个对象(列表),然后将该对象传递给应用程序进行显示等

为了最大限度地利用LINQ对对象的影响,我假设您首先必须获取员工的所有数据,然后应用LINQ过滤对象,只显示女性员工。这样做的好处是,您可以继续查询员工,而无需再次触摸数据库

这是一个基本的例子,但我想指出的是效益和高效执行时间之间的界限在哪里

如果employee表有100000条记录呢

我可以看到LINQ的好处。。。。但在我看来,我确信首先需要将所有数据放入一个对象中,然后使用LINQ进行查询

当我每次需要不同的数据子集时都可以再次查询数据库时,获取所有数据的成本可能太高,不值得


想法?

如果您只需要数据的一个子集作为开始,请只获取该子集。我认为在您的示例中获取所有员工数据是没有意义的

然而,这并不意味着LINQ to Objects很少有用——通常当您已经获得一些数据(很可能不是来自数据库的数据)时(例如,我发现它对反射非常有用),您希望以多种方式对其进行切片和切分。LINQtoObjects是一个非常强大的工具


就我个人而言,我发现LINQtoObjects是最引人注目的LINQ提供者。很容易预测它将做什么(因为不涉及翻译),而且它在应用程序的每一层都很有用。当我编写Java时,我非常想念它——几乎每当我对集合做任何有趣的事情时,LINQ to Objects都会让它变得更简单。

LINQ不仅仅是关于数据库

简而言之,它为您提供了对结构(可以是行、XML、内存中的对象列表等)的查询功能(有DB或没有DB)。因此,您不必编写代码来手动执行操作&它更具可读性

想象一下,不得不比较两个列表&试图用C#代码在其中找到共同的元素。使用SQL执行此操作将很容易理解,但在c#中执行相同的操作只需要很少的代码(除非您尝试这样做,否则它将不可读)

LINQ提供了语法糖,这使您看起来像是在编写SQL来查询/排序/聚合事物。大多数开发人员都可以阅读SQL

编辑:假设您拥有希望向用户显示的数据子集。现在,您需要某种过滤/聚合/排序操作,这样您就不必使用数据库来完成所有这些操作,您将如何做到这一点


如果有什么东西将我的集合视为某种可查询、可排序、聚合的结构(类似于SQL中的表)?

当您处理数据库中的数据时,您是应该依赖LINQ访问对象还是在数据库中执行查询,这会变得很模糊。我认为,一般来说,如果您有一个数据库,最好在数据库中尽可能多地进行过滤和排序,并节省使用LINQ来处理对象,尤其是在大型数据集合上

然而,由于DAL代码可能有点笨重,我发现有时在DAL中运行FindAll查询,然后使用LINQ to对象进行排序和筛选更容易。(但仅当您的收藏量较小时)


LINQtoObjects对于在内存集合上执行类似数据库的排序和过滤非常有用。这可能是您从数据库中提取的一个集合,需要进一步过滤,但也可能是代码中的任何集合。

您可以使用LINQ查询数据库,而不仅仅是查询数据库。类似于LINQ到数据库实体/XML/etc从延迟处理中获益的方式;对数组、集合、对象图和几乎任何您能想到的其他内存结构的查询也是如此。我所说的延迟处理是指;您可以定义查询(分配给变量),直到您开始枚举结果,它才真正执行。此外,LINQ的谓词逻辑指向任何可链接的对象;想想过滤

例如,假设您想要创建一个字符串扩展方法,该方法去掉标点和空格。可以对字符串创建如下查询:

public static string RemovePunctuation(this string @string)
{
    if (string.IsNullOrEmpty(@string))
        return @string;

    var bytes = (
        from ch in @string
        where !Char.IsPunctuation(ch) && !Char.IsWhiteSpace(ch)
        select Convert.ToByte(ch)
        ).ToArray(); // <- calling to array enumerates the results

    return UnicodeEncoding.ASCII.GetString(bytes);
}
公共静态字符串删除标点符号(此字符串@string)
{
if(string.IsNullOrEmpty(@string))
返回@string;
变量字节=(
从chin@string
其中!Char.ispuncuation(ch)和&!Char.IsWhiteSpace(ch)
选择Convert.ToByte(ch)

).ToArray();//使用哲学?这里有一个通用答案,您可以在其他地方使用

阅读一些工具有用的例子。如果你发现自己缺乏使用该工具的理由,因为类似的例子永远不会出现在你身上,那么就忘了它。它可能不适用于你的领域

如果您正在处理的所有数据都在RDBMS中,那么您可能根本不需要Linq to对象

另一方面,您可能认为这是对数据库中的数据进行额外操作的一种方式,因此错过了加强与数据库无关的代码表达能力的机会

示例:您正在读取一个由几行纯文本组成的文件

var lines = File.ReadAllLines(fileName);
碰巧,
现在包含一个字符串数组,但是数组支持IEnumerable,所以我们可以对它们使用Linq方法
var nonBlankLines = lines.Where(line => line.Trim() == string.Empty);
var quoted = lines.Where(line => line.Trim() == string.Empty)
                  .Select(line => "\"" + line + "\"");
var quoted = File.ReadAllLines(fileName)
                 .Where(line => line.Trim() == string.Empty)
                 .Select(line => "\"" + line + "\"");
var quoted = string.Join(", ", 
                         File.ReadAllLines(fileName)
                             .Where(line => line.Trim() == string.Empty)
                             .Select(line => "\"" + line + "\"")
                             .ToArray());
var quoted = File.ReadAllLines(fileName)
                 .Where(line => line.Trim() == string.Empty)
                 .Select(line => "\"" + line + "\"")
                 .Aggregate((a, b) => a + ", " + b);
IEnumerable<T> Generate<T>(T item, Func<T, T> generator)
{
    for (; item != null; item = generator(item))
        yield return item;
}
MessageBox.Show(Util.Generate(x, i => i.InnerException).Last().Message);