【问题标题】:System.InvalidCastException with Comparing Two DatatablesSystem.InvalidCastException 比较两个数据表
【发布时间】:2016-03-25 18:30:32
【问题描述】:

我在使用 LINQ 比较 C# 中的两个数据表时遇到了问题。该应用程序的目的是从 3 个不同的 Oracle 数据库中获取数据并将所述数据传输到 MySQL 数据库。在应用程序内部,我拉出两个表并比较它们以查找 MySQL 表中缺少的行并添加它们。

MySQL 数据库中的表使用三个主键,因为我从中获取的数据可能包含重复项。相同的数据被发送到三个 Oracle 数据库中的每一个,但它们位于不同的环境服务器上。即(生产,登台等...)我可以通过添加环境列将所有三个放入一个数据表中,这样它们的行就不会重复,但是当我比较并找到丢失的行并尝试将它们复制到一个新数据表我总是得到无效的强制转换异常。

我正在从 Oracle 数据库中获取第一个表,然后对表进行克隆并设置克隆表的数据类型。

    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);

添加数据类型后,我将所有三个不同的数据表导入到一个中,并将它们与 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();

这是错误的图片:

我不明白为什么我会收到错误,因为我确保 DataTypes 匹配,因此非常感谢任何帮助。此外,如果有人有更好的方法来做到这一点,而不是使用 LINQ,请随时发布。

【问题讨论】:

  • 这些数据库字段是否可以为空?如果是这样,您的 .Net 类型需要匹配。
  • @Seano666 它们都不能为空
  • 我的元素在这里,但似乎其中之一正在抛出:table1.Field&lt;Int64&gt;("CASEID")。我会验证然后从那里开始搜索,例如a maybe related SO post。此外,如果底层数据类型与 Int64 不兼容,那么我敢打赌 o1Clone.Columns["CASEID"].DataType = typeof(Int64) 没有做你想做的事。您是在说“这是一个 Int64 数据类型”,即使它可能与 Int64 完全不兼容且无法转换为。

标签: c# database linq datatables


【解决方案1】:

经过大量的反复试验,我找到了可行的解决方案。

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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-20
    • 2015-09-26
    • 1970-01-01
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多