Я пытаюсь импортировать таблицы и представления из базы данных Oracle с помощью ODAC 12c Release 4 и Visual Studio 2015 с EF 6 в модель .edmx.
Я прекрасно могу импортировать большинство таблиц и представлений, но некоторые из них содержат ошибки, и я не могу понять, как их исправить. В частности, у меня возникают проблемы с двумя типами ошибок:
- Внешние ключи с неправильным типом данных. Обычно столбец внешнего ключа NUMBER соединен со столбцом NUMBER(9,0). Они будут преобразованы в десятичные числа и int32, что приведет к ошибкам.
- Представления без первичных ключей.
Ранее я использовал ODAC 11 с EF 5, где я мог устранить эти ошибки следующим образом:
- Импорт добавит проблемные таблицы на диаграмму и укажет на ошибку. Чтобы исправить это, все, что мне нужно было сделать, это изменить типы данных в модели.
- Чтобы получить первичный ключ, я добавил ROW_NUMBER() AS ID в качестве столбца и установил его в качестве первичного ключа с отключенным ограничением CONSTRAINT ID_PK PRIMARY KEY (ID) DISABLE. Это позволило бы мне импортировать представление, но я все равно получил бы ошибку о том, что первичные ключи могут быть нулевыми, поэтому я создал скрипт, который добавлял бы Nullable=False для всех первичных ключей. После этого все будет работать нормально.
Попытка импортировать таблицы и представления с этими проблемами с помощью нового программного обеспечения гораздо более проблематична. Вместо того, чтобы сначала импортировать, а потом указывать на ошибки, мне вообще нельзя импортировать. Вот где я застрял для двух проблем:
Попытка добавить таблицы с этой проблемой не удастся без объяснения причин. Ничего не будет добавлено ни в диаграмму, ни в модель, ни в model.store. Добавление одной таблицы за раз позволяет мне добавить любой конец проблемного соединения с внешним ключом, но попытка добавить другую таблицу просто выдаст эту ошибку, а затем ничего не сделает:
«Модель была создана с предупреждениями или ошибками. Model.edmx. Дополнительные сведения см. в списке ошибок. Эти проблемы необходимо устранить перед запуском приложения».
Но список ошибок будет пуст. Я даже не вижу, какая таблица вызывает проблему, чтобы помочь мне исправить проблему в базе данных.
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;