【问题标题】:Incomprehensible problem between MongoDB and Oracle (dynamic assembly)MongoDB和Oracle之间难以理解的问题(动态组装)
【发布时间】:2021-10-14 23:25:48
【问题描述】:

我遇到了类似的问题,例如Oracle DataAccess related: "The invoked member is not supported in a dynamic assembly."

我遇到了相同的 Oracle 异常(“动态程序集中不支持调用的成员”)。 但是,我认为 Oracle 版本不是问题,因为该程序在此之前运行良好,并且 Oracle 版本是相同的。它与自定义 oracle 数据类型 (SdoGeometry) 的支持有关。

[OracleCustomTypeMappingAttribute("MDSYS.SDO_GEOMETRY")]
public class SdoGeometry : OracleCustomTypeBase<SdoGeometry> { ... }

注意:到目前为止它运行良好。

程序尝试从 oracle 数据库中获取一些数据,然后计算并将结果存储在 MongoDB 数据库中。由于 MongoDB 部分最近有一些发展(有什么联系?我到了那里),在某些情况下我会遇到异常。

所以,程序的工作原理如下:

1. If there is data in MongoDB, the program checks it
2. The program selects data in Oracle and prepares it
3. It stores data in MongoDB

有时)失败的操作在第 2 步:它包括在输出数据中添加列类型名称,如下所示:

private void ReadTypes(Dictionary<string, string> types, DbDataReader reader){
   if (types.Count == 0) {
      int fieldCount = reader.FieldCount;
      for (int i = 0; i < fieldCount; i++) {
         string fieldName = reader.GetName(i);
         try {
            string fieldType = reader.GetFieldType(i).Name;
            types[fieldName] = fieldType;
         }
         catch (Exception e) {
            // the invoked member is not supported in a dynamic assembly
            // only for SdoGeometry type
         }
      }
   }
}

OracleDataReader.GetFieldType(i) 对于 SdoGeometry 类型(我们的自定义数据类型)仅在执行第 1 步时失败(存在一些 MongoDB 操作)。我已经确定了负责的操作,它是:

mongoEvents = mongoEvents_.Find(e => e.Identifier.Table.Equals(table)).ToList();

(通过逐行移动 if-true-return 块 - 在我没有显示的应用程序的一部分上 - 我确定是这个操作产生了错误)。

此操作包括从 Mongo 中提取已为当前 Oracle 表存档的数据。这是 MongoAPI (IMongoCollection.Find) 的操作。所以:

  • 如果我注释这一行并返回一个空列表(或手动插入的对象),则不会再出现异常。嗯...
  • 但奇怪的是:
//I've replaced the previous statement. 
//It's working, no mongo data is returned but this is independent of step 2, 
//which in any case retrieves data from Oracle database.

//(MongoDataEvent is one of our classes which defines the structure of archived data)

mongoEvents = new List<MongoEvent.MongoDataEvent>(); 

好的,但如果不是这样,我在前一个语句之后添加这个语句:

mongoEvents = mongoEvents_.Find(e => e.Identifier.Table.Equals(table)).ToList();
mongoEvents = new List<MongoEvent.MongoDataEvent>(); 

好吧没用,但是在执行Find方法后清空列表时,再次出现异常(不是在调用Find时,而是在调用GetFieldType之后),而列表是空的。

所以...我不知道发生了什么。有任何想法吗 ?谢谢。

【问题讨论】:

  • 只是为了确保我理解:当类型为SDO_GEOMETRY 时,调用reader.GetFieldType(i) 失败并且如果有时在您完成某些特定于mongodb 的操作之前?跨度>
  • 但是你也说这个 sometimes 失败了,即使之前有 mongodb 咒语?会不会只发生在您获取的某些类型的几何对象上? SDO_GEOMETRY 类型包含其他几种对象类型,以及一些数组(Oracle VARRAY 类型)。可能与这些数组的大小有关吗?其中一个数组包含形成几何的点的坐标。难道这个问题只有在这个数字很大时才会出现?它可能会上升到 1000000。
  • 该应用程序始终以相同的方式工作:1)它检查 MongoDb 数据是否仍然引用 Oracle 中的现有数据,2)用最新的 oracle 数据填充 mongodb。当 mongodb 最初为空(应用程序首次启动)时,SdoGeometry 总是正确的。所有 SdoGeometry 都可以并存储在 mongoDb 中。但是,当应用程序第二次启动时,它执行 1) 和 2) -> 当它是 2) 时,程序从 oracle 数据读取 SdoGeometry 时系统性地失败(使用相同的函数).. 错误就像“被调用的动态程序集中不支持成员”(仅适用于 SdoGeometry,其他字段都可以)。
  • 好的,谢谢。所以它总是无法读取几何对象 - 这不是 iWork 对某些人而言,而是对其他人而言失败。那么这是否曾经奏效过?看起来是这样。你说“它一直运作良好”。所以这意味着某些事情发生了变化:处理发生了变化。或者正在处理的数据发生了变化。
  • 您还说:“所有 SdoGeometry 都可以并存储在 mongoDb 中”。那是怎么发生的 ?使用相同的应用程序?或者通过其他途径。 SDO_GEOMETRY 是一种对象类型,它本身包含其他对象类型和可变长度数组。阅读它们比阅读简单的标量(包括字符串)更复杂。 DbDataReader 类是什么?那是由 MongoDB 提供的吗?你确定它支持读取Oracle对象类型吗?

标签: c# .net mongodb oracle oracle-spatial


【解决方案1】:

我找到了解决办法!

通过在我的程序的第一条语句中简单地添加一个 Oracle(虚拟)查询,对任意选择的表的 SdoGeometry 类型字段进行选择。

我认为这会强制加载 SdoGeometry 类型。

据我了解,在加载 Oracle SdoGeometry 数据之前查询 MongoDb 数据时发生了错误,在程序集中加载时出现问题 (?)。

不过,这个解决方案非常有效!每次我尝试它都有效并且一旦我尝试注释掉强制 SdoGeometry 加载的请求,错误总是会再次发生。此外,MongoDb 数据看起来是正确的。

我不了解细节中的所有内容,但它有效!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-20
    • 2018-10-15
    • 1970-01-01
    • 2019-06-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 2017-02-03
    相关资源
    最近更新 更多