Entity Framework и ассоциации между строковыми ключами

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

Мы конвертируем в MSSQL и хотим использовать EF в качестве ORM, но столкнулись с проблемой.

Вот пример, который иллюстрирует нашу проблему:

TableA имеет первичный строковый ключ, TableB имеет ссылку на этот первичный ключ.

В LINQ мы пишем что-то вроде:


var result = from t in context.TableB select t.TableA;
foreach( var r in result )
    Console.WriteLine( r.someFieldInTableA );  

если TableA содержит первичный ключ, который читает "A", а TableB содержит две строки, которые ссылаются на TableA, но с разными регистрами в поле ссылки, "a" и "A".

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

Используя SQL Profiler, я заметил, что обе строки выбраны.

Есть ли способ сообщить Entity Framework, что ключи не чувствительны к регистру?

Редактировать:
Теперь мы проверили это с помощью NHibernate и пришли к выводу, что NHibernate работает с ключами без учета регистра. Так что NHibernate может быть лучшим выбором для нас.
Однако я все еще заинтересован в том, чтобы выяснить, есть ли способ изменить поведение Entity Framework.


Спасибо за Ваш ответ!

Проблема заключается в том, что если мы добавим это ограничение к базе данных сейчас, устаревшее приложение может перестать работать из-за того, как оно построено. Лучше всего для нас было бы, если возможно, изменить поведение EF. Я предполагаю, что это невозможно, но я делаю это.


С Уважением,
Фредрик

редактировать: причина, по которой я добавил ответ на свой собственный вопрос, заключалась в том, что я добавил этот вопрос до того, как стал зарегистрированным пользователем, и когда я зарегистрировал свой аккаунт, я не мог добавлять комментарии или редактировать свое сообщение. Теперь аккаунты объединены.

5 ответов

Решение

Я думаю, вам нужно внести изменения в схему в SQL Server, а не в EF. Ответ этого поста о том, как сделать столбец чувствительным к регистру, выглядит так, как будто он сработает: T-SQL: Как создать уникальный ключ, чувствительный к регистру?

Я знаю, что это не идеальное решение, но в LINQ почему бы не сделать это самостоятельно. EF не работает, потому что.Designer.cs файл возвращает objA.Equals(objB) при выполнении соединения. .Equals чувствителен к регистру.

var result = from t1 в context.TableB объединить t2 в context.TableA для t1.someFieldInTableB.ToUpper() равно t2.someFieldInTableA.ToUpper();

Я знаю, что это так, но LINQ to Entities все еще находится в зачаточном состоянии, и разработанные классы объектов разработаны по особым причинам, которые не обрабатывают исключительные случаи в такой конструкции.

Другой альтернативой является то, что вы можете создать свой собственный генератор кода, используя шаблоны T4. Поскольку все является открытым частичным классом, вы можете создать свойство навигации, которое фактически выполняет сравнение без учета регистра, которое вы ищете.

Однако, чтобы ответить на ваш вопрос правдиво, не существует "готового" способа заставить EF выполнять навигацию с использованием поиска без учета регистра.

Я знаю, что это не идеальное решение, но в LINQ почему бы не сделать это самостоятельно. EF не работает, потому что файл.Designer.cs возвращает objA.Equals(objB) при выполнении >> соединения..Equals чувствителен к регистру.

Ну, нет, если вы переопределите метод Equals

Сгенерированные доменные классы в EF частичные нет? Так что довольно просто заменить реализацию Equals по умолчанию этих классов вашими собственными реализациями (что, конечно, сделает его нечувствительным к регистру)

Кстати: техника датируется с.NET 1.0

Со всем этим.NET 3.5/4.0, Linq и Lambda насилие, люди склонны забывать об основах

Я нашел обходной путь, который "сшивает" строковую ассоциацию в памяти после того, как контекст извлек строки из базы данных (подсказка: использование контекста.[EntityTypeCollection].Локальное свойство. Мой ответ вы можете увидеть на /questions/45631003/entity-framework-code-chuvstvitelnost-k-pervomu-registru-na-strokovyih-otnosheniyah-pkfk/45631019#45631019

В качестве альтернативы Entity Framework вы можете использовать LINQ to SQL, который хорошо работает с отношениями, включающими сортировку с учетом регистра. Хотя этот ORM не предлагает всей гибкости EF или NHibernate, во многих случаях этого может быть достаточно.

Недавно я разместил ветку на официальном форуме Microsoft Entity Framework: http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/d4aa6880-31b3-4ff2-b7f5-e2694d76772e

Другие вопросы по тегам