Свойства навигации при несовпадении типов данных в Entity Framework

Я пытаюсь сопоставить устаревшую базу данных с моделью Entity Framework. База данных очень универсальна, и большинство данных хранится в таблицах «Объект» и «Событие». Столбцы имеют такие названия, как «Date1», «Num11», «Text4». В базе данных нет явных внешних ключей.

Вот подмножество двух таблиц:

CREATE TABLE [Object] (
    [ObjectId] int not null identity(1,1) primary key,
    [ObjectTypeId] int,
    [Name] varchar(100)
);

CREATE TABLE [Event] (
    [EventId] int not null identity(1,1) primary key,
    [EventTypeId] int,
    [Subject] text,
    [Body] text,
    [Date1] datetime,
    [Num11] decimal(18,2)
);

Для некоторых значений EventTypeID поле Num11 ссылается на Object. Я могу легко написать соединение между таблицами:

SELECT
    ev.[EventId], ev.[Subject], ev.[Body], ev.[Date1] AS [CreatedDate],
    p.[ObjectId] AS [PersonId], p.[Name] AS [PersonName]
FROM [Event] ev
LEFT JOIN [Object] p ON p.ObjectId = ev.Num11
WHERE ev.[EventTypeId] = 7
AND ev.[Date1] > '2013-04-07'

В конструкторе Entity Framework я могу создавать отдельные Entities для каждого типа объекта и соответствующим образом переименовывать столбцы. Проблемы начинаются, когда я пытаюсь создать свойства навигации между объектами, поскольку тип столбца внешнего ключа не всегда соответствует первичному ключу.

Ни SQL Server, ни Entity Framework не позволят мне создать ссылку внешнего ключа между столбцами.

Как я могу создать свойства навигации между объектами, если типы данных FK an и PK не совпадают в точности? Что-то, что позволяет мне включить связанный объект в запрос LINQ и, надеюсь, предоставить его в службе OData.

Я не могу вносить какие-либо изменения в существующие таблицы в базе данных, но при необходимости могу добавить представления. Хотя мне нужно будет сохранить объекты обратно в базу данных.


person Markus Jarderot    schedule 08.04.2013    source источник


Ответы (2)


Дизайн не из приятных, но есть еще кое-какие варианты. Вот что вы можете делать:

  • Создайте представление 1: 1 для Event с дополнительным столбцом, преобразующим десятичное число в целое число. Свойство следует пометить как вычисленное.
  • Используйте свойство в ассоциации FK с Object, поэтому Object имеет свойство навигации EventViewItems (если хотите), которое отображается на представление. (Вы должны добавить связь вручную в дизайнере edmx и настройте поле внешнего ключа).
  • Прочтите объекты и события в одном операторе linq, например db.Objects.Include(o => o.EventViewItems)

Но ты не можешь

Таким образом, вам придется также включить исходный Event в модель и использовать его для создания / обновления / удаления (CUD) отдельных объектов Event.

Ощущается, но шатко, потому что вам нужно следить за своими шагами, чтобы не столкнуться с исключениями во время выполнения. С другой стороны, у вас будут отдельные пути для чтения и CUD. Назовите это CQRS, и этот дизайн внезапно стал передовым.

person Gert Arnold    schedule 08.04.2013
comment
В итоге я отбросил всю идею и вручную запросил связанные объекты. Обходной способ использования отдельных сущностей запроса и обновления требует слишком много времени для реализации. Я принимаю этот ответ, потому что он решит то, о чем я просил, даже если я не воспользуюсь им. - person Markus Jarderot; 10.04.2013

Вы можете попробовать это. Измените тип Num11 в модели на целое число. В efconfiguration события установите для типа базы данных num11 значение int с помощью xx.HasColumnType ("int").

person Dennis Bischof    schedule 08.04.2013
comment
Я попробую это. Если бы я смог заставить его работать, это было бы самым простым решением. Мое чутье подсказывает, что мне придется изменить поле на int для всех подклассов, отображаемых в столбце. - person Markus Jarderot; 09.04.2013
comment
Как я думал. EF не позволит мне иметь два сопоставления с одним и тем же столбцом с разными типами. - person Markus Jarderot; 10.04.2013
comment
Это нормально. Если вам нужен другой тип, вы не можете использовать это решение. - person Dennis Bischof; 15.04.2013