LINQ DataTable选择唯一行

3
我正在尝试获取具有每个重复行总和的不同行
DataTable newItems = new DataTable();

newItems.Columns.Add("Qty");
newItems.Columns.Add("BarcodeNumber");
newItems.Columns.Add("DisplayName");
newItems.Columns.Add("UnitPrice");
newItems.Columns.Add("TotalPrice");

newItems.Rows.Add(1, "URT29384", "Wallet", 88.8, 88.8);
newItems.Rows.Add(1, "URT29233", "Mouse", 4.44, 4.44);
newItems.Rows.Add(1, "URT29756", "Flash Drive", 1.47, 1.47);
newItems.Rows.Add(1, "URT29323", "Spoon", 99.95, 99.95);
newItems.Rows.Add(1, "URT29384", "Wallet", 88.8, 88.8);
newItems.Rows.Add(1, "URT29384", "Wallet", 88.8, 88.8);

i want the result to be

 3 URT29384  Wallet       266.4     266.4
 1 URT29233  Mouse          4.44      4.44
 1 URT29756  Flash Drive    1.47      1.47
 1 URT29323  Spoon         99.95     99.95

这是否可以使用LINQ来实现?需要一些帮助。谢谢您的关注。

这可以使用LINQ实现吗?是的。 - Nikhil Agrawal
仅为离题建议:价格应存储为 System.Decimal。参见 https://dev59.com/pHM_5IYBdhLWcg3w6X5e#1165788 - Cristian Lupascu
3个回答

6

是的,你可以使用Enumerable.GroupBy

var result = newItems.AsEnumerable()
            .GroupBy(r => r.Field<String>("BarcodeNumber"))
            .Select(g => new { 
                Qty = g.Count(),
                BarcodeNumber = g.Key,
                DisplayName = g.First().Field<String>("DisplayName"),
                UnitPrice = g.Sum(r => r.Field<double>("UnitPrice")),
                TotalPrice = g.Sum(r => r.Field<double>("TotalPrice")),
            })
            .OrderByDescending(x => x.Qty);

请注意,这不是一个DataTableIEnumerable<DataRow>,而是一个带有列的匿名类型。如果需要,您需要使用foreach循环将真正的DataRows添加到另一个DataTable中。
foreach (var grp in result)
    Console.WriteLine("Qty:{0} BarcodeNumber:{1} DisplayName:{2} UnitPrice:{3} TotalPrice:{4}"
        , grp.Qty, grp.BarcodeNumber, grp.DisplayName, grp.UnitPrice, grp.TotalPrice);

您需要添加using System.Linq;


能否将结果强制转换为 DataTable? - Vincent Dagpin
啊,那个.. 没有必要转换为数据表。 - Vincent Dagpin
发布了一个将其放入数据表中的答案。 - Jan P.
如果你有数据库层,那么在那里处理这个问题会更有效率和容易,特别是当你预期处理大量记录的时候。 - Gregor Primar
@VincentDagpin,是的,可以将其“转换”为DataTable: DataTable dt = new DataTable(); dt = linqquery.CopyToDataTable(); - Maciej Los

1
private static DataTable GetUniqueEntries(DataTable dt)  
    {  
        var query = (  
        from row in dt.AsEnumerable()  
        select row.Field<string>("UserName")).Distinct();  //any column <UserName>

        DataTable dtDistinctNames = new DataTable();  
        dtDistinctNames.Columns.Add("UserName", typeof(string));  

        //have to return a datatable, thus loop through entries  
        foreach (string item in query)  
        {  
            DataRow newRow = dtDistinctNames.NewRow();  
            newRow["UserName"] = item;  
            dtDistinctNames.Rows.Add(newRow);  
        }  

        return dtDistinctNames;  
    }

1

是的,这是可能的。

var foo = newItems.AsEnumerable()
    .GroupBy(item => item.Field<string>(newItems.Columns["BarcodeNumber"]));

DataTable newTable = new DataTable();

newTable.Columns.Add("Qty");
newTable.Columns.Add("BarcodeNumber");
newTable.Columns.Add("DisplayName");
newTable.Columns.Add("UnitPrice");
newTable.Columns.Add("TotalPrice");

foreach (var item in foo)
{
    newTable.Rows.Add(
    item.Count(),
    item.Key,
    item.First().Field<string>(newItems.Columns["DisplayName"]),
    item.Sum(row => decimal.Parse(row.Field<string>(newItems.Columns["UnitPrice"]))),
    item.Sum(row => decimal.Parse(row.Field<string>(newItems.Columns["TotalPrice"]))));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接