Как отфильтровать объекты коллекции IQueryable с помощью свойства объектов из другой коллекции IQueryable используя операции where и contains

165
02 февраля 2020, 09:10

Есть две коллекции IQueryable:

  1. IQueryable<> Users со свойствами объекта, одно из которых Id
  2. IQueryable<> AuthorizationLogs cо свойствами объекта, одно из которых userId (что-то вроде внешнего ключа к Id из коллекции Users).

Как с помощью операций where и contains можно отфильтровать коллекцию AuthorizationLogs по свойству Id из коллекции Users и вывести count отфильтрованных объектов в коллекции.

По сути реализовал то, что мне нужно через foreach. Смущает большое количество итераций, т.к. каждая из коллекций содержит по 100+ объектов.

foreach (var user in users)
{
    foreach (var auth in authUsers)
    {
         if (user.Id == auth.UserId) tCount++;
    }
}
Answer 1

для начала, перевести коллекцию в List, например:

var list1 = source1.Select(s=>new { s.Id, s.Name }).ToList();
var list2 = source2.Select(s=>new { s.Id, s.Name }).ToList();

Второе, сопоставить и выбрать:

var T = from a in list1
from b in list2
where a.Id == b.Id
select b;
int count = T?.Count();
Answer 2

Как-то так:

void Main()
{
    IQueryable<User> users = new List<User>()
    {
        new User { Id = 1, A = 123 },
        new User { Id = 2, A = 222 },
        new User { Id = 3, A = 333 },
    }.AsQueryable();
    IQueryable<AuthorizationLog> logs = new List<AuthorizationLog>()
    {
        new AuthorizationLog { UserId = 1, B = 011 },
        new AuthorizationLog { UserId = 2, B = 021 },
        new AuthorizationLog { UserId = 2, B = 022 },
    }.AsQueryable();
    var count = this.GetCount(users, logs);
    //count.Dump();
}
public int GetCount(IQueryable<User> users, IQueryable<AuthorizationLog> logs)
{
    return logs.Count(x => users.Any(y => y.Id == x.UserId));
}
// Define other methods and classes here
public class User : TWithId
{
    public int A { get; set; }
}
public abstract class TWithId
{
    public int Id { get; set; }
}
public class AuthorizationLog : TWithUserId
{
    public int B { get; set; }
}
public abstract class TWithUserId
{
    public int UserId { get; set; }
}

P.S. С передачей критерия отбора можно уходить куда-то сюда:

public int GetCount(IQueryable<User> users, IQueryable<AuthorizationLog> logs, Expression<Func<User, bool>> criteria)
{
    return logs.Count(x => users.Where(u => x.UserId == u.Id).Any(criteria));
}
    var count = this.GetCount(users, logs, x => x.Id != 0 && x.Id < 3);
READ ALSO
Не запускается проект на ASP.NET Core

Не запускается проект на ASP.NET Core

Пишу в консоле dotnet buildВыдает ошибку

144
Ввод чисел с клавиатуры внутри цикла в C#

Ввод чисел с клавиатуры внутри цикла в C#

У меня возникла проблема: я должен ввести числа с клавиатуры внутри цикла forМой код:

143
Неверный порядок в структуре json(newtonsoft) c# winforms

Неверный порядок в структуре json(newtonsoft) c# winforms

Я сохраняю в json-файл введённые данныеТак же есть блоки, которых может быть неограниченное количество(динамические), которые я добавляю по нажатии...

135
Ввод данных в массив класса c#

Ввод данных в массив класса c#

Есть метод LoadStudents, который записывает в массив класса Student объекты с некоторыми полямиНеобходимо разработать метод (я пытался, назвал его...

168