条件和合并数据表,同时数据从一个替换到另一个

时间:2018-03-22 05:08:25

标签: c# .net linq

我的C#Windows窗体应用程序中有两个数据表;

DataTable dtProduct;
DataTable dtDetails;

dtProduct正在填充MS AccessdtDetails来自MySql,其中包含以下类似记录

dtProduct

code   | pNameOrignal
----------------------
101    | product one
220    | product two 
65     | product three
104    | product four
221    | product five 
654    | product six

dtDetails

id | tid | code | pNameLocal        | qty | price
-------------------------------------------------
1  |101  | 101  | some_local_name   | 2   |20.36
2  |102  | 202  | some_local_name   | 1   |15.30 // same entry as same tid and all same 
3  |102  | 202  | some_local_name   | 1   |15.30 //same entry as same tid and all same
4  |102  | 202  | some_local_name   | 1   |10.00 //same entry as same tid but price is different
5  |102  | 202  | some_local_name   | 2   |15.30 //same entry as same tid but different qty
6  |102  | 202  | some_local_name2  | 1   |15.30 //same entry as same tid but pNameLocal different
7  |103  | 202  | some_local_name   | 1   |15.30 // different entry of same product see different tid
8  |104  | 65   | some_local_name   | 5   |05.00
9  |105  | 700  | some_local_name   | 2   |07.01 // does not exist in "dtProduct"

我目前根据dtdetails列的唯一性循环浏览dtProduct pNameOrignal的所有记录,以dtProduct替换code的产品dtDetails.Rows .Cast<DataRow>() .Join ( dtProduct.Rows.Cast<DataRow>(), r1 => new { p1 = r1["code"], p2 = r1["code"] }, r2 => new { p1 = r2["code"], p2 = r2["code"] }, (r1, r2) => new { r1, r2 } ) .ToList() .ForEach(o => o.r1.SetField("pNameLocal", o.r2["pNameOrignal"])); 的原始名称在两个表中。我现有的代码看起来像这样;

code = 700

现在需要什么

  1. 需要将相同的tid和所有相同的相同条目合并或创建一行,方法是将数量设为2(如当前记录中所示)将两者和价格加到30.60(如当前记录中)

    说明:多个完全相同的记录(重复记录)合并为一行,方法是根据记录数保留其数量和价格。

  2. tid = 105 的条目({1}}中不存在dtProduct,它不会从那里替换pOrignalName,会保持不变当前我的代码名称,我需要添加或连接&#34; NotFound&#34;用这个名字。

2 个答案:

答案 0 :(得分:1)

第二点用匹配的记录替换名称,并为不匹配的记录添加“NotFound”。

 var k =  (from d in dtDetails.AsEnumerable() join
         k1 in dtProduct.AsEnumerable() on d["code"] equals k1["code"] into dk1
         from subset in dk1.DefaultIfEmpty()
         select new { d, subset }).ToList();

foreach (var m in k)
{
    if (m.subset != null)
    {
        if (string.Equals(m.d["code"], m.subset["code"]))
        {
            m.d.SetField("pNameLocal", m.subset["pNameOrignal"]);
        }
    }
    else
    {
        m.d.SetField("pNameLocal", m.d["pNameLocal"] +"NotFound");
    }
}

第一个试试这个

   dtDetails = dtDetails.AsEnumerable()
    .GroupBy(r => new { Col1 = r["tid"], Col2 = r["code"], Col3 = r["pNameLocal"] })
    .Select(g =>
    {
        var row1 = dtDetails.NewRow();

        row1["tid"] = g.Key.Col1;
        row1["code"] = g.Key.Col2;
        row1["pNameLocal"] = g.Key.Col3;
        row1["qty"] = g.Sum(r => r.Field<int>("qty"));
        row1["price"] = g.Sum(r => r.Field<decimal>("price"));

        return row1;
    })
    .CopyToDataTable();

答案 1 :(得分:0)

对于您提到的第2点,可以这样做:

foreach (DataRow item in dtDetails.Rows)
{
  var pNameOriginal = dtProduct.AsEnumerable().FirstOrDefault(i => i.Field<int>("code") == item.Field<int>("code"));
  var globalName = "NotFound";
  if (pNameOriginal != null && !string.IsNullOrEmpty(Convert.ToString(pNameOriginal.ItemArray[1])))
  {
    globalName = Convert.ToString(pNameOriginal.ItemArray[1]);
  }

  item["pNameLocal"] += globalName;
}

我仍然不清楚你在第1点想要什么。在你的情况下,如何计算一个组的计数为2。你可以通过拍摄102来解释吗?