Как в Identity for Entity Framework Core 3.x найти пользователей по электронной почте (с учетом нормализации), когда уникальность электронной почты не применяется? - PullRequest
1 голос
/ 14 января 2020

userManager.FindByEmailAsync(myEmail) выдает исключение, если есть несколько пользователей с одним и тем же адресом электронной почты.

Я мог бы использовать:

await context.ApplicationUsers
    .FirstOrDefaultAsync(x => x.NormalizedEmail == myEmail.ToUpperInvariant());

Кажется, все в порядке. Но я не уверен, является ли ToUpperInvariant правильным способом проверки, потому что System.Text также имеет Normalize (). Это не имеет значения сейчас, так как мы используем SQL Сервер с конфигурацией без учета регистра, но я не хочу, чтобы что-то сломалось, если мы когда-либо изменим это.

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

1 Ответ

4 голосов
/ 14 января 2020

Нормализация выполняется не ядром EF, а классом UserManager (с использованием службы ILookupNormalizer , внедренной через конструктор или установленной через свойство KeyNormalizer ).

UserManager.FindByEmailAsync метод выполняет для вас нормализацию перед вызовом метода store. Проблема заключается в том, что реализация метода хранилища EF Core использует SingleOrDefaultAsyn c, который выдает, если в базе данных есть дублированные нормализованные электронные письма.

Чтобы исправить это, вы можете использовать UserManager. NormalizeEmail метод для нормализации, а затем используйте FirstOrDefaultAsync запрос, как в вашем примере:

var normalizedEmail = userManager.NormalizeEmail(myEmail);
var firstDuplicate = await userManager.Users
    .FirstOrDefaultAsync(x => x.NormalizedEmail == normalizedEmail);
...