Entity Framework nvarchar Чувствительность к регистру на внешнем ключе - PullRequest
8 голосов
/ 17 марта 2012

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

У меня есть две таблицы

Users
UserName nvarchar(250) Primary Key
FirstName nvarchar(50)
LastName  nvarchar(50)

Registrations
Id BigInt PrimaryKey
User nvarchar(250) - Foreign to Users Table
Date - DateTime

Data I have is as follows.
Users
UserName FirstName LastName
a        Small     A 
b        Small     B

Registrations
Id       User      Date
1        A         1/1/12
2        B         1/1/12

Обратите внимание, что регистр пользователя здесь Caps, он действителен в SQL, он принимает.

Теперь самое интересное. Я сгенерировал EDMX, .Net 4.0 и теперь я выполняю этот код.

 using (EFTestEntities context = new EFTestEntities())
            {
                var item = context.Registrations.Where(id => id.Id == 1).FirstOrDefault();
                Response.Write(item.User1.LastName);
            }

Он просто разрывается с исключением нулевого указателя. Пользователь1 сбрасывает ноль. Когда я изменяю значение столбца UserName в таблице регистрации на a вместо A , это работает.

Это Ссылка говорит о чем-то похожем

Это Ссылка Еще одна похожая проблема

Пожалуйста, поделитесь своими ответами, почему это происходит, сортировка моей БД не учитывает регистр. Сталкивались ли вы с подобным?

Ответы [ 2 ]

11 голосов
/ 17 марта 2012

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

При вызове item.User1.LastName EF запускает отложенную загрузку - в базе данных выполняется дополнительный запрос для загрузки связанного пользователя, но когда материализуется пользователь, EF начнет исправлять и проверять свою реляционную модель, и здесь возникает проблема - он сравнивает строки с чувствительностью к регистру, поэтому в соответствии с этим параметром a не равен A, и поэтому загруженный объект User не является отношением вашего объекта Registration. В результате EF не исправит свойство User1 и останется нулевым. Доступ к LastName в таком случае вызовет NullReferenceException.

Есть только два решения:

  • Исправьте вашу базу данных и убедитесь, что эта разница не будет больше отображаться в ваших данных
  • Если вы находитесь в начале проекта или если у вас есть полный контроль над базой данных, перепроектируйте ее. NVarChar первичные ключи и внешние ключи не подходят для базы данных.

Если ни один из этих вариантов не подходит для вас, вам следует избегать использования EF с такой базой данных.

0 голосов
/ 30 марта 2019

@ Ладислав отлично описал проблему, но есть и другой подход, который могут использовать некоторые люди. Отдельные столбцы в ваших таблицах могут быть сделаны с учетом регистра, поэтому они ведут себя так же, как .Net;

Users
UserName nvarchar(250) collate Latin1_General_CS_AS Primary Key
FirstName nvarchar(50)
LastName  nvarchar(50)

Registrations
Id BigInt PrimaryKey
User nvarchar(250) collate Latin1_General_CS_AS - Foreign to Users Table
Date - DateTime

Обратите внимание на сопоставление , добавленное к определениям столбцов. Теперь (при условии, что у вас определен внешний ключ) база данных будет обеспечивать согласованность регистра только для имени пользователя между обеими таблицами. Возможно, вам придется заранее подготовить данные, установив для всех значение upper / lower, и, возможно, вам придется отбрасывать и воссоздавать индексы, ограничения и т. Д. При использовании alter table.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...