Запрос отношения «многие ко многим» со списком параметров - PullRequest
0 голосов
/ 01 января 2019

Я использую ядро ​​EF, и у меня есть классы «Пользователь» и «Полномочия», которые связаны отношением «многие ко многим» («Пользователи» имеют свойство «полномочия», а «Полномочия» имеют свойство «пользователи»).).Отношения управляются через средний класс «UserAuthority».

Мне нужно запросить всех «пользователей» с «полномочиями» с определенными именами.

Я пробовал это:

List<string> authorities = A list of authorities;
(from user in this.dbContext.user.Include("authorities.authority")
 where authorities.Any(x => user.authorities.Any(y => y.authority.authority == x))
 select new UserDto(user.id, user.firstname + " " + user.lastname)).ToList()

Но консоль говорит, что LINQ не может перевести

authorities.Any(x => user.authorities.Any(y => y.authority.authority == x))

и что он будет обработан в памяти.

Какой здесь правильный подход?

Ответы [ 2 ]

0 голосов
/ 02 января 2019

Вы писали:

У меня есть классы «Пользователь» и «Полномочия», которые связаны отношением «многие ко многим» («Пользователи» имеют свойство «полномочия» и «Полномочия»)."имеет свойство" пользователи ").

Примерно так:

class User
{
    public int Id {get; set;}
    ...

    // every User has zero or more Authorities (many-to-many)
    public virtual ICollection<Authority> Authorities {get; set;}
}
class Authority
{
    public int Id {get; set;}
    public string Name {get; set;}
    ...

    // every Authority has zero or more Users (many-to-many)
    public virtual ICollection<User> Users {get; set;}
}

Мне нужно запросить всех «пользователей» с «полномочиями» с определенными именами.

Если я читаю это буквально, вы хотите, чтобы все Users имели хотя бы один Authority с Name в коллекции certainNames.Вы хотите, чтобы каждый User со ВСЕМИ его Authorities, даже те Authorities с именами, которых нет в certainNames

Это также может означать, что вы хотите все Users, каждый с только теми изих Authorities, которые имеют Name, который находится в certainNames, но только те Users, у которых есть хотя бы один такой Authority.

Как насчет этого:

IEnumerable<string> certainNames = ...
var UsersWithAuthoritiesThatAreInCertainNames = myDbContext.Users
    .Where (user => user.Authorities.Select(authority => authority.Name)
         .Intersect(certainNames)
         .Any())
    .Select(user => new
    {
         // select only the User properties you actually plan to use:
         Id = user.Id,
         Name = user.Name,
         ...

         Authorities = user.Authorities.Select(authority => new
         {
             // again select only the Authority properties you plan to use:
             Id = authority.Id,
             Name = authority.Name,
             ...
         })
         .ToList(),
    })

Другими словами:

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

Если вы не хотите ВСЕ полномочия пользователя, а только те, которые имеют определенные имена:

var UsersWithOnlyTheirAuthoritiesThatAreInCertainNames = myDbContext.Users
    .Select(user => new
    {
         // select only the User properties you actually plan to use:
         Id = user.Id,
         Name = user.Name,
         ...

         Authorities = user.Authorities
         .Where(authority => certainNames.Contains(authority.Name))
         .Select(authority => new
         {
             // again select only the Authority properties you plan to use:
             Id = authority.Id,
             Name = authority.Name,
             ...
         })
         .ToList(),
    })
    // keep only the Users that have at least one such authority
    .Where(selectedUser => selectedUser.Authorities.Any());

В словах:

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

0 голосов
/ 01 января 2019

В настоящее время единственным переводимым методом сбора в памяти является Contains (для сбора в памяти примитивного типа переводится в SQL IN(...)).

Таким образом, вместо

authorities.Any(x => user.authorities.Any(y => y.authority.authority == x))

использовать

user.authorities.Any(ua => authorities.Contains(ua.authority.authority))
...