Найти все объекты в одном списке, у которых есть свойство, совпадающее со свойством в другом списке объектов - PullRequest
2 голосов
/ 25 февраля 2020

Проблема

Я пытаюсь запросить таблицу (на основе ModelA), используя другую таблицу (на основе ModelB). Эти модели упрощены для этого примера. Мне нужно сохранить результат как IQueryable, поэтому изменение на Enumerable или List не вариант. Тем не менее, я попытался добавить .ToList(), но получил ту же ошибку.

Извлечение MyId из одного списка в список строк (для использования Contains()) не вариант, так как может быть слишком много MyIds (> 40 КБ), что приводит к ошибке, указывающей на операцию как нехватку ресурсов, что, я думаю, относится к ОЗУ.

Ошибка

InvalidOperationException: выражение LINQ ... не может быть переведено. Либо переписать запрос в форме, которую можно перевести, либо явно переключиться на оценку клиента, вставив вызов либо AsEnumerable (), AsAsyncEnumerable (), ToList (), либо ToListAsyn c ().

Модель A

public class ModelA
{
    public string MyId { get; set; }
    public string MyName { get; set; }
}

Модель B

public class ModelB
{
    public string MyId { get; set; }
    public string MyName { get; set; }
}

Попытка

var results = context.ModelA
            .Where(a => ModelB.All(b => b.MyId == a.MyId));

Каким образом это можно сделать успешно?

Ответы [ 4 ]

2 голосов
/ 26 февраля 2020

Вы можете попробовать это:

var results = ctx
    .ModelAs
    .Where(ma => ctx.ModelBs.Any(mb => mb.MyId == ma.MyId));

Я использовал ваши модели, это мои DbContext:

public class MockContext : DbContext
{
    public MockContext(DbContextOptions<MockContext> options)
        : base(options)
    { }

    public DbSet<ModelA> ModelAs { get; set; }
    public DbSet<ModelB> ModelBs { get; set; }
}

Данные, которые я использовал для проверки, были:

Модель A:

MyId | MyName

1 Nettie Koch 
2 Karl Kuvalis 
3 Marcus Weissnat 
4 Shannon Hettinger 
5 Wilma Kuvalis 
6 Benny Brown 
7 Amanda Maggio 
8 Claude Kohler 
9 Dawn Ritchie 
10 Alan Ruecker

Модель B:

MyId | MyName

5 Francis Konopelski 
6 Mandy Yost 
7 Marsha Parisian 
8 Crystal Mayer 
9 Sergio Crona 
10 Kenny Rice 
11 Levi Gutkowski 
12 Brandon Haley 
13 Jan Kunze 
14 Rafael Blanda 

Результат:

MyId | MyName

5 Wilma Kuvalis 
6 Benny Brown 
7 Amanda Maggio 
8 Claude Kohler 
9 Dawn Ritchie 
10 Alan Ruecker 
1 голос
/ 27 февраля 2020

Возможно, вы ищете Any(), как показано ниже

var results = context.ModelA.Where(a => ModelB.Any(b => b.MyId == a.MyId));
1 голос
/ 26 февраля 2020

Есть несколько способов, которыми вы можете достичь этого, вот два способа для справки:

var result = (from a in context.ModelA
                      join b in context.ModelB
                      on a.MyId equals b.MyId
                      select a);

Или вы можете попробовать этот метод:

 var result = context.ModelA.Join(_context.ModelB,
                        x => x.MyId,
                        y => y.MyId,
                       (x, y) => x);

Вы можете обратиться к эта ссылка для более подробной информации.

1 голос
/ 25 февраля 2020

вы можете попробовать проверить, содержит ли второй список 'Any ()' с соответствующим идентификатором

var results = context.ModelA
        .Where(a => ModelB.Where(b => b.MyId == a.MyId).Any());

или вы можете попробовать присоединиться

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/join-clause

var results = context.ModelA
    .Where(a => ModelB.
            Any(b => b!= null  && b.id != null 
                  && a!=null && a.id!==null && 
                  b.MyId == a.MyId));

У меня был выбор вместо где, и я проверил на нули

...