好吧,我越用LINQ,就越喜欢它!我最近发现自己在工作中使用了一些遗留代码。它是您的经典DataSet和DataTable富应用程序。好吧,当添加一些功能时,我发现自己真的只想查询DataTable的行,以获得我想要的结果。
让我重复一遍。。。我只是想向Rows集合询问我需要什么,而不是循环并添加到临时集合中。没有循环,没有临时变量,只要给我我想要的。
var customerOrderIds = table.Rows.Cast<DataRow>()
.Where(x => (string)x["CUSTOMER_ID"] == customerId)
.Select(x => (string)x["CUSTOMER_ORDER_ID"])
.Distinct();
我的问题是这是否是一件好事,还是被LINQ冲昏头脑了在我看来,这种从集合中提取数据子集的声明性风格是一件好事,而且最终更具可读性。但话说回来,也许我只是被迷住了:)
另一个观察结果;如果您不使用类型化数据集,您可能还想了解Field<>
扩展方法:
var customerOrderIds = table.Rows.Cast<DataRow>()
.Where(x => x.Field<string>("CUSTOMER_ID") == customerId)
.Select(x => x.Field<string>("CUSTOMER_ORDER_ID"))
.Distinct();
或者使用查询语法:
var customerOrderIds = (
from row in table.Rows.Cast<DataRow>()
where row.Field<string>("CUSTOMER_ID") == customerId
select row.Field<string>("CUSTOMER_ORDER_ID")
).Distinct();
我并不是说它是好是坏,只是另一个可行的选择。
(实际上,我不太使用DataTable
,所以YMMV)
对我来说似乎很好——尽管我会尝试使用强类型数据集,这会使LINQ查询看起来更令人愉快。
但是,是的,LINQ是一件非常好的事情——与进程外的LINQ提供者相比,LINQ to Objects(以及XML和DataSet的周围技术)是非常可预测的。(与LINQ to SQL相比,它不那么性感,但适用范围更广。)
查询看起来不错。
我想指出两件小事。
无循环
System.Linq.Enumerable方法根据IEnumerable(T)约定进行操作,这几乎总是意味着循环-O(N)解决方案。这有两个含义:
- 首选Any()而不是Count()>0。Any()是O(1)。Count()是O(N)
- 加入。。。所有联接都是嵌套循环O(M*N)
.铸造
.Cast适用于DataTable.Rows(所有这些对象都是行,所以强制转换总是成功的)。对于异类集合,请注意.OfType(),它会过滤掉任何无法强制转换的项。
最后,请注意,查询只有在枚举后才会执行!您可以通过foreach、ToList、ToArray、First、Single等强制枚举。
就我个人而言,由于数据表本身没有能力进行选择性区分,所以我认为它并没有那么糟糕。
不过,我可能会问,是否有任何方法可以最终使用对象而不是数据表,因为我认为这会让未来的开发人员更容易理解。
你一点也不忘乎所以。在LINQ to DataSets上发布了一些实际的工作。有了这样清晰、声明性的对象查询,代码的可维护性就容易多了。但你必须记住,在你过滤数据的时候,所有的数据都已经被撤回了。您可能需要考虑将筛选添加到DataSet查询的SQL中。
你的代码很好。
联接(使用联接关键字,但不使用from关键字)使用Dictionary进行匹配,因此是O(M+N)
。
分组也是如此,但不包括以下内容:
from x in Xs
from y in Ys
.Where(o => o == x)
select new
{
x,
y
}
即CCD_ 4。