C# - 如何在LINQ的where语句中使用带参数的Expression
C# - 如何在LINQ的where语句中使用带参数的Expression
任务:我需要在LINQ
的where子句中使用带参数的表达式从数据库
中获取一些数据,但是出现了错误。
这是一个工作表达式的示例:
var shopExp = GetPersonForShop(PersonTypeIds.Director, new Guid("adda423f-8c38-40e0-9f39-6deceb787bc0")); // id Where(shopExp)
但是我需要动态分配id,但是出现了上面的错误:
_repository.Persons .Where(GetPersonForShop(PersonTypeIds.Director, person.PersonId)
并且出现了错误:
{"无法将类型为'System.Linq.Expressions.InstanceMethodCallExpression2'的对象强制转换为类型'System.Linq.Expressions.LambdaExpression'。"}
Where(linq)
函数是什么样的:
private Expression> GetPersonForShop(PersonTypeIds personTypeId, Guid personId) { return person => person .PeronTypeId== (int) personTypeId && person .PersonId == personId; }
这大致上是我们生产环境的样子,只是改变了参数代码的名称。
如何将带参数的表达式添加到Where
子句中?
在使用LINQ进行数据查询时,有时候会遇到需要在多个地方重复使用相同的查询条件的情况。如果直接在代码中多次写入相同的查询条件,会导致代码的冗余和可维护性的下降。为了解决这个问题,可以使用Expression
下面是一个示例代码,展示了如何使用Expression
Expression> 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> 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 IQueryableFilterByTypeAndId(IQueryable datasource, Guid idToFind) { return datasource.Where(p => p.TypeId == PersonTypeIds.Director && p.PersonId == idToFind); }
通过使用Expression
问题的出现原因是在LINQ查询中,使用了Expression
解决方法是通过将参数值传递给Expression
以下是解决方法的示例代码:
var idToFind = new Guid("adda423f-8c38-40e0-9f39-6deceb787bc0"); Expression> filterExpression = p => p.TypeId == PersonTypeIds.Director && p.PersonId == idToFind; var result = _repository .Persons .Where(filterExpression) .ToList();
在上述代码中,我们首先创建了一个Lambda表达式filterExpression,该表达式接受Person类型的参数p,并检查TypeId和PersonId是否与指定的值匹配。然后,我们将filterExpression传递给Where方法来执行LINQ查询,并使用ToList方法将结果转换为列表。
通过正确传递参数值,我们可以在LINQ查询中使用Expression