2016-11-07 1 views
1

Я имею два DataTables, как показано ниже,Слияние двух DataTables с проверкой C#

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


dt1 
RowId Stk 
2  2 
4  7 

Мне нужно, чтобы объединить эти два DataTables производить ниже результата, в основном, если ROWID существуют в dt1, нужно минус ее акции кол-во из dtOrigin dtNew

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; 
     } 
+1

Если вы используете LINQ к SQL, то вы можете использовать linq join выражение –

+0

Какое исключение он бросает? 'NullReferenceException'? 'InvalidArgumentException'? 'BetweenKeyboardAndChairException'? Почти никто не может помочь, если вы не предоставите достаточно деталей. –

+0

@ZevSpitz, исключение равно {«Значение не может быть пустым. \ R \ nParameter name: row"} –

ответ

1

Попробуйте это:

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

Я предполагаю, что, когда нет соответствующей записи во второй DataTable, stuff будет null, вызывая NullReferenceException при попытке прочитать значение для этой строки. Это выражение:

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

означает «если stuff является null, то все выражение должно вычисляться null, в противном случае она должна вернуть значение из поля».

Это еще не эогух; потому что вы не можете вычесть null из чего-то другого. Он должен быть передан ?? оператора:

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

, что означает, что если левая сторона не null затем использовать это значение, в противном случае использовать 0.

+0

Он работает частично. Я имею в виду, что если RowId существует в обеих таблицах, он вычитает Stk и отображает правильно, но те продукты, которые не находятся во второй таблице, но присутствуют в 1-й таблице, всегда отображают STK = 0, даже если первая таблица имеет значение для STK –

+0

Можете ли вы показать все выражение, которое вы используете для 'Stock = ???'? –

+0

обновил вопрос со всем выражением –