Entity Framework - Размышляя об иностранных ключах и отношениях / ассоциациях - PullRequest
5 голосов
/ 13 ноября 2011

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

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

Причина, по которой я пытаюсь это сделать, заключается в том, что у меня есть большое количество таблиц (около 40), которые ссылаются на одну таблицу элементов. Допустим, пользователь вводит новое значение в таблицу элементов под названием «Andew», а позже администратор замечает, что на самом деле это просто опечатка для уже существующего элемента «Andrew». Теперь я хочу найти все ссылки на «Andew» и изменить эти ссылки на «Андрей». Я бы предпочел сделать это эффективно, поэтому использование свойств обратной навигации будет слишком медленным, так как вы должны загрузить значения перед их изменением. Что я хотел бы сделать, так это уметь отображать список таблиц и столбцов, а затем вводить команды обновления непосредственно в базу данных. Это будет выглядеть примерно так:

var command = String.Format("UPDATE [{0}] SET [{1}] = {{1}} WHERE [{1}] = {{0}}; ", fk.FromTableName, fk.FromColumnName);
dataContext.ExecuteStoreCommand(command, new Object[] { oldID, newID });

В LINQ to SQL это было на самом деле довольно просто ... 20 строк размышлений об автоматически сгенерированном коде LINQ, и я закончил, но мы недавно перешли на EF, и я не могу найти имена столбцов внешнего ключа через EF.

Упрощенный пример того, что я ищу: если у меня есть объект с именем Employee со свойством навигации, называемым Manager, и внешним ключом ManagerID, я хочу знать, что Manager - это мое свойство навигации, а базовое хранилище - это свойство ManagerID. Я хочу сделать это строго с помощью рефлексии или метаданных, чтобы из него можно было построить динамический запрос.

Ответы [ 3 ]

1 голос
/ 14 ноября 2011

Просто чтобы сэкономить время, я хочу выбросить это не правильный ответ, но вы можете делать то, что я спрашиваю, через системные представления в SQL.Я попробовал это, и это работает, но это беспокоит меня, я мог бы так легко получить эти данные через LINQ to SQL, но я вообще не могу найти их в EF.Если нет альтернативы, мне придется использовать приведенное ниже решение.(Но EF должен иметь эти данные где-то внутри ... Я просто хочу получить к ним доступ.)

select K.name as RelationshipName, T1.name as FromTable, C1.name as FromColumn, T2.name as ToTable, C2.name as ToColumn
from sys.foreign_keys as K
join sys.foreign_key_columns as C on K.object_id = C.constraint_object_id
join sys.columns as C1 on K.parent_object_id = C1.object_id 
join sys.tables as T1 on K.parent_object_id = T1.object_id 
join sys.columns as C2 on K.referenced_object_id = C2.object_id
join sys.tables as T2 on K.referenced_object_id = T2.object_id 
where C1.column_id = C.parent_column_id
and C2.column_id = C.referenced_column_id
and T2.Name = 'Employee'
order by T1.Name, C1.Name

Надеюсь, публикация этого неправильного ответа, по крайней мере, будет полезна кому-то, кроме меня ... (также,только для справки, для этого решения требуется намного больше кода для работы с многостолбцовыми ПК - у меня все одноколоночные).

1 голос
/ 14 ноября 2011

Как только вы использовали идеи в связанном вопросе, чтобы добраться до интересующего вас EntityType, обратите внимание, что EntityType наследуется от EntityTypeBase, у которого есть свойство KeyMembers, которое является коллекциейвсе EdmMembers, которые участвуют в ключе сущности.

Каждый EdmMember имеет Name, который будет строкой "ManagerID", которую вы ищете.

0 голосов
/ 17 ноября 2011

Ответ на вопрос находится в другом посте здесь: Прочитайте метаданные внешнего ключа программно с Entity Framework 4

Обратите внимание, что ответ автора не сработал для меня.Используйте ответ @ Ашрафа, который отлично сработал.

...