2016-03-25 2 views
0

У меня возникла проблема с сравнением двух таблиц данных в C# с использованием LINQ. Целью приложения является получение данных из 3 различных баз данных Oracle и передача указанных данных в базу данных MySQL. Внутри приложения я вытягиваю обе таблицы и сравниваю их, чтобы найти строки, отсутствующие в таблице MySQL, и добавить их.System.InvalidCastException с сопоставлением двух Datatables

В таблице из базы данных MySQL используются три первичных ключа, поскольку данные, которые я захватываю, могут содержать дубликаты. Те же данные отправляются в каждую из трех баз данных Oracle, но они находятся на разных серверах среды. Т.е. (производство, постановка и т. Д.). Я могу выбросить все три в одну таблицу данных, добавив столбец среды, чтобы они не дублировались, но когда я сравниваю и обнаруживаю недостающие строки и пытаюсь скопировать их в новая таблица данных. Я всегда получаю недопустимое исключение.

Я захватываю первую таблицу из базы данных Oracle, затем создаю клон таблицы и устанавливаю DataTypes клонированной таблицы.

o1Clone.Columns["CASEID"].DataType = typeof(Int64); 
    o1Clone.Columns["CASENAME"].DataType = typeof(string); 
    o1Clone.Columns["CREATEDDATE"].DataType = typeof(DateTime); 
    o1Clone.Columns["STUDYMODEID"].DataType = typeof(int); 
    o1Clone.Columns["ENVIRONMENT"].DataType = typeof(string); 

После добавления DataTypes я импортирую все три разных типа данных в один и сравниваю их с базой данных MySQL.

var matched = from table1 in oClone.AsEnumerable() 
          join table2 in mClone.AsEnumerable() on table1.Field<Int64>("CASEID") equals table2.Field<Int64>("CASEID") 
          where table1.Field<string>("CASENAME") == table2.Field<string>("CASENAME") || table1.Field<DateTime>("CREATEDDATE") == table2.Field<DateTime>("CREATEDDATE") || table1.Field<int>("STUDYMODEID") == table2.Field<int>("STUDYMODEID") || table1.Field<string>("ENVIRONMENT") == table2.Field<string>("ENVIRONMENT") 
          select table1; 
      var missing = from table1 in oClone.AsEnumerable() 
          where !matched.Contains(table1) 
          select table1; 
      DataTable mm = missing.CopyToDataTable(); 

Вот картина ошибки: Error

Я не понимаю, почему я получаю сообщение об ошибке, потому что я убедившись, что Datatypes матч так что любая помощь с этим была бы оценена. Также, если у кого-то есть лучший способ сделать это, а не использовать LINQ, не стесняйтесь публиковать сообщения.

+0

Является ли какое-либо из этих полей базы данных допустимым? Если это так, ваши .Net-типы должны соответствовать. – Seano666

+0

@ Seano666 ни один из них не может быть нулевым – SWard

+0

Из моего элемента здесь, но кажется, что один из них бросает: 'table1.Field (" CASEID ")'. Я бы проверил, что тогда начните искать в Интернете, например, [возможно, связанную SO-почту] (http://stackoverflow.com/questions/35227563/oracle-dataaccess-datarow-fielddecimal-invalidcastexception). Кроме того, если базовый тип данных несовместим с Int64, я делаю ставку 'o1Clone.Columns [" CASEID "]. DataType = typeof (Int64)' не делает то, что вы хотите. Вы говорите: «Это Int64 DataType», хотя он может быть полностью несовместим с Int64 и не конвертируется в него. – Quantic

ответ

0

После многих проб и ошибок я смог найти решение, которое работает.

var matched = from table1 in oClone.AsEnumerable() 
       join table2 in mClone.AsEnumerable() on table1.Field<decimal>("CASEID") equals table2.Field<Int64>("CASEID") 
       where table1.Field<decimal>("CASEID") == table2.Field<Int64>("CASEID") || 
       table1.Field<string>("CASENAME") == table2.Field<string>("CASENAME") || 
       table1.Field<DateTime>("CREATEDDATE") == table2.Field<DateTime>("CREATEDDATE") || 
       table1.Field<int>("STUDYMODEID") == table2.Field<int>("STUDYMODEID") || 
       table1.Field<string>("ENVIRONMENT") == table2.Field<string>("ENVIRONMENT") 
       select table1; 
var missing = from table1 in oClone.AsEnumerable() 
       where !matched.Contains(table1) 
       select table1;