Как устранить проблемы при импорте базы данных Oracle в модель Entity Framework с помощью ODAC 12c Release 4 и EF 6?

Я пытаюсь импортировать таблицы и представления из базы данных Oracle с помощью ODAC 12c Release 4 и Visual Studio 2015 с EF 6 в модель .edmx.


Я прекрасно могу импортировать большинство таблиц и представлений, но некоторые из них содержат ошибки, и я не могу понять, как их исправить. В частности, у меня возникают проблемы с двумя типами ошибок:

  1. Внешние ключи с неправильным типом данных. Обычно столбец внешнего ключа NUMBER соединен со столбцом NUMBER(9,0). Они будут преобразованы в десятичные числа и int32, что приведет к ошибкам.
  2. Представления без первичных ключей.


Ранее я использовал ODAC 11 с EF 5, где я мог устранить эти ошибки следующим образом:

  1. Импорт добавит проблемные таблицы на диаграмму и укажет на ошибку. Чтобы исправить это, все, что мне нужно было сделать, это изменить типы данных в модели.
  2. Чтобы получить первичный ключ, я добавил ROW_NUMBER() AS ID в качестве столбца и установил его в качестве первичного ключа с отключенным ограничением CONSTRAINT ID_PK PRIMARY KEY (ID) DISABLE. Это позволило бы мне импортировать представление, но я все равно получил бы ошибку о том, что первичные ключи могут быть нулевыми, поэтому я создал скрипт, который добавлял бы Nullable=False для всех первичных ключей. После этого все будет работать нормально.


Попытка импортировать таблицы и представления с этими проблемами с помощью нового программного обеспечения гораздо более проблематична. Вместо того, чтобы сначала импортировать, а потом указывать на ошибки, мне вообще нельзя импортировать. Вот где я застрял для двух проблем:

  1. Попытка добавить таблицы с этой проблемой не удастся без объяснения причин. Ничего не будет добавлено ни в диаграмму, ни в модель, ни в model.store. Добавление одной таблицы за раз позволяет мне добавить любой конец проблемного соединения с внешним ключом, но попытка добавить другую таблицу просто выдаст эту ошибку, а затем ничего не сделает:

    «Модель была создана с предупреждениями или ошибками. Model.edmx. Дополнительные сведения см. в списке ошибок. Эти проблемы необходимо устранить перед запуском приложения».

    Но список ошибок будет пуст. Я даже не вижу, какая таблица вызывает проблему, чтобы помочь мне исправить проблему в базе данных.

  2. Before adding row number as a primary key the view will be added to model.store but commented out with this error:

    "Error 6013: The table/view '[ViewName]' does not have a primary key defined and no valid primary key could be inferred. This table/view has been excluded. To use the entity, you will need to review your schema, add the correct keys, and uncomment it."

    After adding row number as a primary key I get this error instead:

    "Error 13101: Key part 'ID' for type '[ViewName]' is not valid. All parts of the key must be non-nullable."

    The view won't be imported at all, giving me no way to fix the problem since Oracle doesn't allow Nullable=False on views. So I can't fix it before importing but I can't import it without fixing it first...


How am I supposed to deal with these problems using ODAC 12c Release 4 and EF 6?

Необходимость возвращаться к ODAC 11 и Visual Studio 2012 с EF 5 каждый раз, когда я хочу импортировать таблицы и представления из базы данных, становится раздражающей.

Поиск других с такой же проблемой дает только несколько обращений и никаких ответов.


РЕДАКТИРОВАТЬ: я нашел решение проблемы с представлениями.

Я создал таблицу 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;

person Telorast    schedule 13.10.2015    source источник
comment
Найден обходной путь для представлений без первичных ключей. Добавил в пост.   -  person Telorast    schedule 26.10.2015
comment
Добавление этого соединения почти в десять раз замедлило мой запрос Where ‹Column› LIKE '%searchTerm%'.   -  person Savo Pejović    schedule 09.01.2020
comment
Но запросы с ID=... работают так же, как и без соединения.   -  person Savo Pejović    schedule 09.01.2020


Ответы (1)


Хорошее решение. работает отлично. Здесь я хочу поделиться 3 дополнения.

  1. ")" отсутствует
  2. вы можете использовать уже существующий вид в качестве исходного вида
  3. добавить "_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; 
person user7447719    schedule 20.01.2017
comment
Пожалуйста, прокомментируйте решение, на которое вы ссылаетесь. Это не ответ сам по себе. - person dckuehn; 20.01.2017
comment
@dckuehn Вероятно, он имеет в виду решение, данное ОП в вопросе. - person Sentry; 23.03.2017