Я пытаюсь выяснить, как я могу получить роли с Any и проверить, существует ли пользователь в том же запросе, и вернуться как SingleOrDefault(), но, похоже, не работает.
private User Authenticate(LoginViewModel model)
{
using (HutLogisticaContext context = new HutLogisticaContext())
{
return context.Users.Where(u => u.Username.Contains(model.Username)).SingleOrDefault();
}
}
Однако он не позволит Meet добавить одиночный или по умолчанию, если я добавлю Any. Как я могу сделать оба по одному запросу?
РЕДАКТИРОВАТЬ
Я забыл упомянуть, но я хочу вернуть пользовательский объект со всеми связанными с ним ролями, не уверен, что это возможно без свойства навигации, потому что я не мог использовать include
public class Role
{
public int Id { get; set; }
public string Nome { get; set; }
public ICollection<User> Users { get; set; }
public ICollection<Claim> Claims { get; set; }
}
public class User
{
public int Id { get; set; }
public string Username { get; set; }
public DateTime? DataSessao { get; set; }
public bool IsActivo { get; set; }
public virtual Colaborador Colaborador { get; set; }
public ICollection<Role> Roles { get; set; }
public ICollection<App> Apps { get; set; }
}
я использую EF 6, так что это автоматически создало таблицу соединений с UserId и RoleId как PK и FK
Это отношение «многие ко многим», поэтому оно должно возвращать каждую роль, где она соответствует идентификатору пользователя, я видел это на примере, я имею в виду, что он должен возвращать объект пользователя со всеми связанными ролями.
Итак, вы хотите перезапустить роль или пользователя?
Я хочу вернуть пользовательский объект с ролями, я не уверен, что это возможно без свойства навигации, хотя
И каковы критерии фильтрации для этого? либо UserID, либо имя пользователя, либо любое другое
UserID, так как таблица соединений имеет только UserID и RoleID
Вы установили PK, FK и доступны ли свойства навигации. Не могли бы вы опубликовать классы пользователей и ролей? и все соответствующие классы?
обновленный основной пост, вы можете проверить
Как вы сказали Я хочу вернуть пользовательский объект с ролями,, вы можете попробовать так => context.Users.Where(x => x.Id == 123).SingleOrDefault();
проблема с этим типом возвращаемого значения функции является пользователь, а роли в конце превращают его в коллекцию
Давайте продолжить обсуждение в чате.
Поскольку ваша пользовательская сущность EF уже имеет настройку ассоциации ролей в качестве свойства коллекции навигации, т.е.
public class User
{
...
public ICollection<Role> Roles { get; set; }
...
Что вы можете сделать, скажите EF, чтобы он загружал эту навигацию, когда вы получаете своего пользователя:
return context.Users
.Include(u => u.Roles) // << i.e. Force EF to Join the UserRoles assocated with User
.Where(...)
.SingleOrDefault()
В вызывающем методе теперь вы можете получить доступ к user.Roles
или использовать логику user.Roles.Any()
, чтобы узнать, есть ли у пользователя роль и т. д.
Есть еще пара вещей
- Поскольку имена пользователей, по-видимому, должны быть уникальными в системе, Contains
(сопоставленный с SQL IN
) кажется здесь неправильным инструментом. Я бы провел прямое сравнение, особенно если у вас есть сортировка без учета регистра по умолчанию в столбце User.UserName
.
- SingleOrDefault также имеет перегрузку, позволяющую использовать тот же предикат, что и фильтр Where
, поэтому вы можете упростить это до:
return context.Users
.Include(u => u.Roles)
.SingleOrDefault(u => u.UserName == model.Username);
Спасибо за правильный ответ, извините, я не могу выбрать его правильно, потому что кто-то дал мне это решение в чате перед этим сообщением.
Ради интереса, почему вы сказали, что не можете использовать .Include
в ОП? Стремительная загрузка с помощью .Include
— это действительно мощный инструмент, который позволяет вам точно определить «глубину» (может быть глубоко вложенным) — соединений таблиц в SQL и легко позволяет вам создавать сущность и все ее отношения в памяти (например, как AggregateRoot в терминология DDD).
Я не уверен, может быть, я сделал ошибку, когда написал include, но когда я попытался, это дало мне исключение из-за отсутствия навигации. Вероятно, синтаксическая ошибка, я еще не очень разбираюсь в EF.
После долгого обсуждения чат приведенный ниже код работает для OP.
private User Authenticate(LoginViewModel model)
{
using (HutLogisticaContext context = new HutLogisticaContext())
{
return context.Users
.Include(u => u.Roles)
.Where(u => u.Id == 123)
.SingleOrDefault();
}
}
Какую роль вы хотите проверить с
Any
?