【问题标题】:Merge two datatables with check c#用check c#合并两个数据表
【发布时间】:2016-11-07 07:12:16
【问题描述】:

我有如下两个数据表,

dtOrigin
RowId Stk   ProdName
 2     245   ABC
 4     144   XYZ
 5     122   ADE


dt1
RowId Stk
 2     2
 4     7

我需要合并这两个数据表以产生以下结果,基本上如果 dt1 中存在 rowid,则需要从 dtOrigin 中减去其库存数量 dt新

RowId Stk           ProdName
 2     243(245-2)   ABC
 4     137(144-7)   XYZ
 5     122          ADE

我可以通过循环来做到这一点,但无论如何都可以在没有循环的情况下做到这一点 谢谢

                    var JoinResult = (from p in dt1.AsEnumerable()
                                      join t in dt2.AsEnumerable()
                                      on p.Field<string>("RowID") equals t.Field<string>("RowID")
                                      into joinedtables from stuff in joinedtables.DefaultIfEmpty()
 select new
                                      {
----------------,
----------------,
Stock = p.Field<Int32>("Stk") - stuff.Field<Int32>("Stk")
}

抛出异常。请指正好吗?


下面是我使用的代码

    var JoinResult = (from p in dt.AsEnumerable()
                                      join t in dt2.AsEnumerable()
                                      on p.Field<string>("RowID") equals t.Field<string>("RowID")
                                      into joinedtables from stuff in joinedtables.DefaultIfEmpty()
                                      select new
                                      {
                                          RowID = p.Field<string>("RowID"),
                                          ProdName = p.Field<string>("ProdName"),
                      STK = p.Field<Int32>("STK") - stuff?.Field<Int32>("STK") ?? 0
                                         }

  dtable = LINQResultToDataTable(JoinResult);




    public static DataTable LINQResultToDataTable<T>(IEnumerable<T> Linqlist)
        {
            DataTable dt = new DataTable();


            PropertyInfo[] columns = null;

            if (Linqlist == null) return dt;

            foreach (T Record in Linqlist)
            {

                if (columns == null)
                {
                    columns = ((Type)Record.GetType()).GetProperties();
                    foreach (PropertyInfo GetProperty in columns)
                    {
                        Type IcolType = GetProperty.PropertyType;

                        if ((IcolType.IsGenericType) && (IcolType.GetGenericTypeDefinition()
                        == typeof(Nullable<>)))
                        {
                            IcolType = IcolType.GetGenericArguments()[0];
                        }

                        dt.Columns.Add(new DataColumn(GetProperty.Name, IcolType));
                    }
                }

                DataRow dr = dt.NewRow();

                foreach (PropertyInfo p in columns)
                {
                    dr[p.Name] = p.GetValue(Record, null) == null ? DBNull.Value : p.GetValue
                    (Record, null);
                }

                dt.Rows.Add(dr);
            }
            return dt;
        }

【问题讨论】:

  • 如果你使用的是 linq to sql 那么你可以使用 linq join 表达式
  • 它抛出了什么异常? NullReferenceException? InvalidArgumentException? BetweenKeyboardAndChairException?如果您不提供足够的详细信息,任何人几乎都无法提供帮助。
  • @ZevSpitz,例外是 {"Value cannot be null.\r\nParameter name: row"}
  • 如果我执行简单的内连接,它可以工作,但我需要左连接
  • 如果行存在于第二个数据表中但不存在于第一个数据表中怎么办?另外,同一个数据表中是否可能有多个具有相同RowID的记录?

标签: c# datatable


【解决方案1】:

试试这个:

var JoinResult = 
                 ...
                 select new {
                     ...
                     Stock = p.Field<Int32>("Stk") - (stuff?.Field<Int32>("Stk") ?? 0)
                 };

我猜当第二个数据表中没有匹配的记录时,stuff 将是null,在尝试读取该行的值时导致NullReferenceException。这个表达式:

stuff?.Field<Int32>("Stk")

意思是“如果stuffnull,那么整个表达式的计算结果应该是null,否则它应该从字段中返回值。”

这还不够;因为你不能从其他东西中减去null。它需要传递给?? 运算符:

stuff?.Field<Int32>("Stk") ?? 0

这意味着如果左侧不是null,则使用该值,否则使用0。

【讨论】:

  • 它正在部分工作。我的意思是,如果两个表中都存在 RowId,它会扣除 Stk 并正确显示,但是那些不在第二个表中但存在于第一个表中的产品始终显示 STK = 0,即使第一个表具有 STK 值
  • @JohnyBravo 尝试用括号括起来:STK = p.Field&lt;Int32&gt;("STK") - (stuff?.Field&lt;Int32&gt;("STK") ?? 0)
猜你喜欢
  • 1970-01-01
  • 2011-12-08
  • 1970-01-01
  • 1970-01-01
  • 2015-10-06
  • 1970-01-01
  • 2012-02-05
  • 1970-01-01
  • 2011-10-13
相关资源
最近更新 更多