使用ODAC 12c Release 4和EF 6将Oracle数据库导入Entity Framework模型时如何解决问题?

时间:2015-10-13 11:17:54

标签: c# oracle entity-framework odac

我尝试使用ODAC 12c Release 4和带有EF 6的Visual Studio 2015将表和视图从Oracle数据库导入到.edmx模型中。


我可以很好地导入大多数表和视图,但其中一些包含错误,我无法弄清楚如何解决这些问题。具体来说,我遇到两种类型的错误:

  1. 数据类型错误的外键。通常是NUMBER外键列连接到NUMBER(9,0)列。这些将被转换为decimal和int32,从而导致错误。
  2. 没有主键的视图。

  3. 以前我使用过ODAC 11和EF 5,我可以通过以下方式解决这些错误:

    1. 导入会将有问题的表添加到图表中并指出错误。要解决这个问题,我所要做的就是更改模型中的数据类型。
    2. 要获取主键,我将ROW_NUMBER()AS ID添加为列,并将其设置为具有禁用约束的主键CONSTRAINT ID_PK PRIMARY KEY(ID)DISABLE。这将允许我导入视图,但我仍然得到关于主键可以为空的错误,因此我创建了一个脚本,为所有主键添加Nullable = False。在此之后一切都会正常。

    3. 尝试使用新软件导入具有这些问题的表和视图更成问题。而不是先导入并指出之后的错误,我根本不允许导入。这是我遇到两个问题的原因:

      1. 如果没有解释,尝试添加有此问题的表将会失败。没有任何内容可以添加到图表,模型和model.store中。一次添加一个表允许我添加有问题的外键连接的任何一端但是尝试添加另一个表只会给出此错误然后什么也不做:

        "模型生成时带有警告或错误。 Model.edmx。有关详细信息,请参阅错误列表。在运行应用程序之前必须修复这些问题。"

        但错误列表将为空。我甚至无法看到导致问题的表格,以帮助我解决数据库中的问题。

      2. 在将行号添加为主键之前,视图将添加到model.store中,但注释掉了此错误:

        "错误6013:表/视图' [ViewName]'没有定义主键,也无法推断出有效的主键。此表/视图已被排除。要使用该实体,您需要检查您的架构,添加正确的密钥并取消注释。"

        将行号添加为主键后,我得到此错误:

        "错误13101:关键部分' ID'对于类型' [ViewName]'无效。密钥的所有部分都必须是不可为空的。"

        该视图根本无法导入,因此Oracle无法解决问题,因为Oracle在视图上不允许Nullable = False。所以我无法在导入之前修复它,但我无法在不修复它的情况下导入它...


      3. 我如何使用ODAC 12c Release 4和EF 6处理这些问题?

        每次我想从数据库导入表格和视图时,必须使用EF 5返回ODAC 11和Visual Studio 2012会变得很烦人。

        搜索具有相同问题的其他人只会给出一些点击而没有答案。

        编辑: 我找到了一个解决问题的方法。

        我创建了一个Row_Number表,其中Row_Number是唯一的列,并使用它加入了视图。由于表中的Row_Number是主键,因此在结果视图中将其标记为Nullable = False,并且可以导入。

        一些代码可以帮助其他人解决同样的问题:

        CREATE TABLE "ROW_NUMBER" 
           (                  "ROW_NUMBER" NUMBER(9,0) NOT NULL ENABLE, 
                               CONSTRAINT "ROW_NUMBER_PK" PRIMARY KEY ("ROW_NUMBER"));
        
        CREATE OR REPLACE PROCEDURE CREATE_ROW_NUMBER IS
        LOOP_ROW_NUMBER NUMBER := 1;
        BEGIN  
          LOOP
            INSERT INTO ROW_NUMBER(ROW_NUMBER)
            VALUES (LOOP_ROW_NUMBER);
            LOOP_ROW_NUMBER := LOOP_ROW_NUMBER + 1;
            IF LOOP_ROW_NUMBER > 1000000 THEN
            EXIT;
            END IF;
          END LOOP;
          COMMIT;
        END CREATE_ROW_NUMBER;
        
        begin
          CREATE_ROW_NUMBER;
        end;
        
        CREATE OR REPLACE FORCE VIEW New_View (“ID”, [COLUMNS]) AS 
          SELECT Row_Number.Row_Number, [COLUMNS]
          FROM Row_Number INNER JOIN (
          SELECT ROWNUM Row_Number, [COLUMNS]
        FROM(
                              SELECT * FROM Table1
                              UNION 
                              SELECT * FROM Table2
        ) Original_View ON Row_Number.Row_Number = Original_View.Row_Number;
        

1 个答案:

答案 0 :(得分:2)

很好的解决方案。工作得很好。在这里,我想分享3个新增内容。

  1. a“)”缺少
  2. 您可以将现有视图用作原始视图
  3. 在别名视图名称
  4. 中添加“_1”

    查询:

    CREATE OR REPLACE FORCE VIEW New_View (“ID”, [COLUMNS]) AS 
        SELECT Row_Number.Row_Number, [COLUMNS]
        FROM Row_Number INNER JOIN (
            SELECT ROWNUM Row_Number, [COLUMNS]
            FROM (SELECT [COLUMNS] FROM Original_View)
            ) Original_View_1 
        ON Row_Number.Row_Number = Original_View_1.Row_Number;