我使用.NET 3.5在C#中编写它。我有一个System.Data.DataSet对象,其中包含一个使用以下模式的DataTable:
Id : uint
AddressA: string
AddressB: string
Bytes : uint
当我运行我的应用程序时,让我们说DataTable充满了以下内容:
1 192.168.0.1 192.168.0.10 300
2 192.168.0.1 192.168.0.20 400
3 192.168.0.1 192.168.0.30 300
4 10.152.0.13 167.10.2.187 80
我希望能够查询这个DataTable,其中AddressA是唯一的,并且字节列被加在一起(我不确定我是否正确地说)。从本质上讲,我想得到以下结果:
1 192.168.0.1 1000
2 10.152.0.13 80
我最终希望将这个结果放在一个可以绑定到DataGrid的DataTable中,我需要每隔5秒左右更新/重新生成一次这个结果。
我该怎么做? DataTable.Select()方法?如果是这样,查询是什么样的?是否有替代/更好的方法来实现我的目标?
编辑:我没有数据库。我只是使用内存中的DataSet来存储数据,因此纯SQL解决方案在这里不起作用。我试图找出如何在DataSet本身内完成它。
答案 0 :(得分:4)
为了便于阅读(因为我喜欢它),我会尝试使用LINQ:
var aggregatedAddresses = from DataRow row in dt.Rows
group row by row["AddressA"] into g
select new {
Address = g.Key,
Byte = g.Sum(row => (uint)row["Bytes"])
};
int i = 1;
foreach(var row in aggregatedAddresses)
{
result.Rows.Add(i++, row.Address, row.Byte);
}
如果使用LINQ解决方案发现性能问题,我会使用手动解决方案将原始表中循环中的行相加并将它们插入结果表中。
您还可以将aggregatedAddresses直接绑定到网格,而不是将其放入DataTable。
答案 1 :(得分:3)
最有效的解决方案是直接在SQL中进行求和
通过AddressA从...组中选择AddressA,SUM(字节)
答案 2 :(得分:2)
我同意Steven的观点,即在服务器端执行此操作是最佳选择。如果你使用的是.NET 3.5,那么你不必经历Rune建议的内容。而是使用数据集的扩展方法来帮助查询和求和值。
然后,您可以轻松地将其映射到匿名类型,您可以将其设置为网格的数据源(假设您不允许对此进行编辑,因为您正在聚合,我不知道如何编辑)数据)。
答案 3 :(得分:1)
我同意Steven的观点,最好的方法是在数据库中执行此操作。但如果这不是一个选项,您可以尝试以下方法:
这将为您提供一个新数据表,其中包含两个表中的组合数据。它不会很快,但除非您拥有大量数据,否则它可能足够快。但是尽量避免在Select中进行LIKE查询,因为那个很慢。
如果两个表都包含具有相同主键的行,则可以进行一种可能的优化。然后,您可以对两个表进行排序,并逐步执行它们使用其数组索引获取两个数据行。这将使你摆脱选择呼叫。