C# - Как использовать выражение <Func>с параметрами в LINQ, где - PullRequest
0 голосов
/ 21 января 2020

Задача: Мне нужно дать некоторое выражение с параметрами в LINQ's, где взять данные из database, но с ошибкой выше. Этот пример рабочего выражения:

var shopExp = GetPersonForShop(PersonTypeIds.Director, new Guid("adda423f-8c38-40e0-9f39-6deceb787bc0")); // id
Where(shopExp) 

Но мне нужно назначать идентификатор динамически, но получена ошибка выше:

_repository.Persons
.Where(GetPersonForShop(PersonTypeIds.Director, person.PersonId)

и получена ошибка:

{"Невозможно привести объект типа 'System.Linq.Expressions.InstanceMethodCallExpression2' к типу 'System.Linq.Expressions.LambdaExpression'. "}

Как выглядит функция для (linq):

private Expression<Func<Person, bool>> GetPersonForShop(PersonTypeIds personTypeId, Guid personId)
        {
            return person => person .PeronTypeId== (int) personTypeId && person .PersonId == personId;
        }

Это приблизительно похоже на производство, просто измените имена параметров код

Как добавить выражение с параметрами в предложение Where ??

Ответы [ 2 ]

0 голосов
/ 21 января 2020

основываясь на предыдущем ответе, я дам вам несколько альтернатив и предложений.

var idToFind = new Guid("adda423f-8c38-40e0-9f39-6deceb787bc0");

var result = _repository
    .Persons
    .Where(p => p.TypeId == PersonTypeIds.Director)
    .Where(p => p.PersonId == idToFind)
    .ToList();

Сначала выполняется предложение where в 2 этапа, а затем добавляется ToList () с ToList (), вы будете иметь дело с коллекциями и LINQ, что довольно полезно. И, выполнив предложение where в 2 шага, вы получите больше информации для чтения.

0 голосов
/ 21 января 2020

Лямбда-выражения используют => нотацию. Попробуйте что-то вроде этого:

var idToFind = new Guid("adda423f-8c38-40e0-9f39-6deceb787bc0");

var result = _repository.Persons
    .Where(p => p.TypeId == PersonTypeIds.Director && p.PersonId == idToFind);

В этом выражении p представляет каждую запись Person в таблице Persons, сравниваемую один за другим, используя логическое выражение, следующее за ним.

В зависимости от вашего источника данных, сравнение для каждого p будет выполнено либо с помощью NET в памяти, либо это произойдет внутри вашей базы данных с использованием предложения SQL WHERE, которое составлено из логического выражения. Последнее было бы оптимальным, потому что это означало бы, что не вся таблица Persons должна быть перенесена в. NET память, прежде чем может быть выполнено сравнение.

Обновление - Чтобы применить то же условие Несколько раз, не повторяя его в своем коде, сохраняя при этом преимущества перевода LINQ в SQL без изменений, вы можете поместить условие в объект Expression<Func<Person, bool>> и затем использовать это несколько раз:

Expression<Func<Person, bool>> expression =
    p => p.TypeId == PersonTypeIds.Director && p.PersonId == idToFind;

var result1 = datasource1.Where(expression);
var result2 = datasource2.Where(expression);
var result3 = datasource3.Where(expression);

Или с помощью метода, который создает объект Expression:

var result1 = datasource1.Where(GetExpression(idToFind));
var result2 = datasource2.Where(GetExpression(idToFind));
var result3 = datasource3.Where(GetExpression(idToFind));

public Expression<Func<Person, bool>> GetExpression(Guid idToFind)
{
    return p => p.TypeId == PersonTypeIds.Director && p.PersonId == idToFind;
}

Или, альтернативно, вы можете использовать вспомогательный метод:

var result1 = FilterByTypeAndId(datasource1, idToFind);
var result2 = FilterByTypeAndId(datasource2, idToFind);
var result3 = FilterByTypeAndId(datasource3, idToFind);

public IQueryable<Person> FilterByTypeAndId(IQueryable<Person> datasource, Guid idToFind)
{
    return datasource.Where(p => p.TypeId == PersonTypeIds.Director && p.PersonId == idToFind);
}
...