Как присоединить таблицу к себе в ядре EF? - PullRequest
0 голосов
/ 26 апреля 2019

У меня есть таблица («ProductParameter»), которая связывает две таблицы («Product» и «Parameter»), в ней есть поля Id, ProductId, ParameterId, Value, у каждого ParameterId есть набор [Value], который мне нужно отфильтровать коллекция сначала по двум ParameterId (где pp.ParameterId = 4 или pp1.ParameterId = 2 и pp1.Value = 'Standard') после фильтрации по одному ParameterId (где pp.ParameterId = 4).

Пример:

+---------+-------------+------------+---------+
|     ID  |  ProductId  |ParameterId | Value   | 
+---------+-------------+------------+---------+
|     25  |    14       |    2       | Standard|
|     26  |    14       |    3       |  CK45   |
|     27  |    14       |    4       |   63    |
|     28  |    15       |    2       |   XXX   |
|     29  |    15       |    3       |  CK45   |
|     30  |    15       |    4       |   70    |
|     34  |    17       |    2       | Standard|
|     35  |    17       |    3       |  CK45   |
|     36  |    17       |    4       |   40    |
|     37  |    25       |    2       | Standard|
|     38  |    25       |    3       |  CK45   |
|     39  |    25       |    4       |   20    |     
+---------+-------------+------------+---------+-

должен вернуть:

+-------+
| Value |  
+-------+
|   63  |   
|   40  | 
|   20  | 
+-------+

Логика запроса следующая:

 select distinct pp.Value from ProductParameters pp
 join ProductParameters pp1 on pp1.ProductId = pp.ProductId and 
 pp1.ParameterId = 2 and pp1.Value = 'Standard'
 where pp.ParameterId = 4

Вот мой запрос в ядре EF:

public async Task<IEnumerable<ProductParameter>> GetProductDiameters(long id, string param = "Standard")
{
    var value = await _context.ProductParameters
        .Include(p => p.Product)
        .ThenInclude(p => p.ProductParameters.Where(i => i.Value == param))
        .Where(p => p.ParameterId == id)
        .Distinct()
        .ToListAsync();

    return value;
}

Исключение выдает:

ArgumentException: лямбда-выражение свойства ThenInclude 'p => {из ProductParameter i в p.ProductParameters, где ([i] .Value == __param_0) select [i]}' недопустимо. Выражение должно представлять доступ к свойству: 't => t.MyProperty'. Чтобы нацелить навигацию, объявленную на производные типы, укажите лямбда-параметр с явно заданным типом целевого типа, например, '(Производный d) => d.MyProperty'.

Где ошибка?

1 Ответ

0 голосов
/ 27 апреля 2019

EF жалуется, потому что вы пытаетесь фильтровать внутри оператора. ThenInclude(..).

var value = await _context.ProductParameters
    .Include(p => p.Product)
    .ThenInclude(p => p.ProductParameters.Where(i => i.Value == param)) //<-- here
    .Where(p => p.ParameterId == id)
    .Distinct()
    .ToListAsync();

Это проблема, потому что EF будет использовать функцию внутри, чтобы определить , какие таблицы следует загружать . Эти функции внутри Include(..) и ThenInclude(..) должны всегда указывать на связанную таблицу, а ничего больше :)

Правильный способ выполнения вашего запроса таков:

var value = await _context.ProductParameters
    .Include(p => p.Product)
    .ThenInclude(p => p.ProductParameters) // <- removed the Where clause from here
    .Where(p => p.ParameterId == id)
    .Where(p => p.ProductParameters.Value == param)) //<- and added it here
    .Distinct()
    .ToListAsync();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...