Разделение объекта, когда ключевой столбец имеет разные имена?

StackOverflow https://stackoverflow.com/questions/9386464

Вопрос

Я использую Entity Framework 4.3.1 Code-First, и мне нужно разделить объект между двумя таблицами. Таблицы имеют общий первичный ключ, равный 1: 1, но столбцы имеют разные имена в каждой таблице.

Я не контролирую структуру данных и не могу запрашивать какие-либо изменения.

Так, например, таблицы SQL могут быть

Таблицы данных SQL

И это будет моя сущность ...

родовое слово

А вот карта, которая у меня есть.

родовое слово

Поскольку общий для них ключ имеет другое имя столбца, я не знаю, как его сопоставить. Это сопоставление будет компилироваться, но не удастся во время выполнения, потому что EF выдает SQL в поисках столбца «ThePrimaryKeyId» в таблице «ExtendedTable», которой не существует.

ИЗМЕНИТЬ Чтобы прояснить, то, что я определил выше, может (и работает) работать, если ПК в «ExtendedTable» следует соглашениям об именах. Но это не так, и я не могу изменить схему.

По сути, то, что мне нужно, чтобы испускать EF, - это оператор SQL, например

родовое слово

Но единственное, что он, кажется, хочет испустить, это

родовое слово

Изменить Я снова попробовал подход 1 к 1 по предложению NSGaga. Не получилось, но вот результаты. Сущности

родовое слово

Вот классы сопоставления

родовое слово

Эта настройка получает сообщение

родовое слово

Изменение последней линии карты на

родовое слово

Возвращает это сообщение

родовое слово

Изменение сопоставленного ключа для использования столбца из родительской таблицы, MapKey("ThePrimaryKeyId"). возвращает это сообщение

родовое слово

Удаление свойства Id из класса ExtEntity вызывает ошибку, поскольку в этом случае объект не имеет определенного ключа.

Это было полезно?

Решение

Я не могу найти ничего, что конкретно указывало бы на то, что имя столбца должно быть одинаковым в обеих таблицах;но я также не могу найти ничего, что говорило бы, что это не так, или объясняло бы, как вы бы сопоставили этот сценарий.Каждый пример, который я могу найти, имеет ключ с тем же именем в обеих таблицах.Мне кажется, это дыра в дизайне DbContext.

Другие советы

Я работал над этой проблемой в течение нескольких дней, и в итоге я установил имя столбца для поля Id в контексте фрагмента сопоставления.Таким образом, вы можете присвоить идентификатору (или внешнему ключу, зависящему от идентификатора) имя, отличное от идентификатора основной таблицы.

родовое слово

Если вы запустите и отладите это, вы обнаружите, что это даст вам что-то вроде того, что вы хотите:

родовое слово

Переместите HasColumnName в сопоставление:

родовое слово

Здесь нет Visual Studio, но попробуйте это с подходом "один к одному":

this.HasRequired (e=> e.ExtendedProperties) .HasConstraint ((e, m)=> e.Id== m.Id);

Обновление:
Вот несколько ссылок, которые могут помочь (не удалось найти настоящую ссылку)

Какдля объявления взаимно однозначной связи с помощью Entity Framework 4 Code First (POCO)
Entity Framework 4 CTP4 Code First: как работать с нестандартными именами первичных и внешних ключей

И просто чтобы предоставить (как я и обещал) сопоставление 1 к 1 (две сущности, две таблицы), чего это стоит.
Вот что работает для меня и должно в вашем случае ...

родовое слово

... и тестовый код вроде ...

родовое слово

Это создает следующий сценарий SQL, таблицы ...

родовое слово

И примечание из нашего обсуждения выше ...
Это не «расщепление», а
(a) сначала код IMO не допускает ничего подобного (я сначала попробовал это, а также изменил миграции вручную, но это «внутренне», все основано на том, что ожидаемые имена столбцов совпадают, и, похоже, нет никакого способа обойти это, поскольку не меньше этой версии EF.
(b) разумная структура таблицы - таблицы могут быть сделаны так, чтобы они выглядели именно так, как вам нужно (как я сказал ранее, я использовал его, чтобы связать существующие таблицы членства aspnet (которые я не мог изменить) в мою таблицу пользователей, у которой есть собственный пользователь -id указывает на внешнюю / aspnet таблицу и идентификатор.
Верно, вы не можете сделать это, используя один класс модели C #, но сторона C # намного более гибкая, и если вы можете контролировать C #, который должен давать тот же эффект, по крайней мере, на мой взгляд (как в тесте, вы всегда можете получить к нему доступ через расширенную сущность, как расширенные, так и основные столбцы, и они всегда сопоставляются 1 к 1 и остаются «синхронизированными».
Надеюсь, это поможет некоторым
ПРИМЕЧАНИЕ: вам не нужно беспокоиться об идентификаторе fk и т. Д. - просто всегда открывайте и добавляйте запись Main через MainEntry, и id-s будет в порядке.

ИЗМЕНИТЬ:
Вы также можете сделать следующее, чтобы создать видимость того, что вам нужно иметь дело только с одним классом (т. Е. Своего рода разделение)

родовое слово

... и используйте его вот так ...

родовое слово

... также вы можете изменить направление fk, выполнив код WithRequiredPrincipal вместо зависимого.
(также все ссылки должны быть без «виртуальных», если вам требуется индивидуальный подход)
(и MainTable можно сделать «внутренним», так как он здесь, поэтому он не виден снаружи - он не может быть вложенным, поскольку EF не позволяет - обрабатывается как NotMapped)
... ну, это лучшее, что я мог сделать :)

Похоже, это было исправлено в Entity Framework 6. См. эту проблему http://entityframework.codeplex.com/ workitem / 388

Я хотел бы предложить использовать некоторые аннотации данных, например:

родовое слово

Я столкнулся с этой проблемой и решил ее, добавив атрибут Column, чтобы он соответствовал именам обоих столбцов. [Key] [Column("Id")] public int GroupId { get; set; }

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top