C# - 如何在LINQ的where语句中使用带参数的Expression

10 浏览
0 Comments

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子句中?

0
0 Comments

在使用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 IQueryable FilterByTypeAndId(IQueryable datasource, Guid idToFind)
{
    return datasource.Where(p => p.TypeId == PersonTypeIds.Director && p.PersonId == idToFind);
}

通过使用Expression>对象或者封装查询条件的方法,可以实现查询条件的复用,简化代码并提高可维护性。

0
0 Comments

问题的出现原因是在LINQ查询中,使用了Expression>作为参数,但是没有正确传入参数值。这导致查询结果不准确。

解决方法是通过将参数值传递给Expression>来正确执行LINQ查询。可以使用Lambda表达式来创建Expression,并将参数传递给Lambda表达式。

以下是解决方法的示例代码:

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>,并得到正确的查询结果。这样可以提高代码的可读性和可维护性。

0