lambda包含在simpleerepository.find
-
03-10-2019 - |
题
在Subsonic 3.04的Simpleerepository中,我似乎无法执行 Contains
在lambda表达式中操作。这是一个琐碎的例子:
SimpleRepository repo = new SimpleRepository("ConnectionString");
List<int> userIds = new List<int>();
userIds.Add(1);
userIds.Add(3);
List<User> users = repo.Find<User>(x => userIds.Contains(x.Id)).ToList();
我收到错误消息:
从范围引用的类型“用户”的变量'x',但未定义
我在这里错过了一些东西,还是不支持亚音话 Contains
在lambda表达式中?如果没有,这将如何完成?
解决方案
由于这些似乎都没有用...
x => guids.Contains(x.Guid)
x => guids.Any(y => y == x.Guid)
...我们编写了生成的自定义lambda表达式构建器:
x => x.Id == {id1} OR x.Id == {id2} OR x.Id == {id3}
这是一个琐碎的情况,但演示了 GetContainsId<User>(ids, repo)
将找到所有具有与所提供列表中某些内容相匹配的ID的用户。
public List<T> GetContainsId<T>(List<int> ids, SimpleRepository repo)
where T : Record, new() // `Record` is a base class with property Id
{
ParameterExpression x = Expression.Parameter(typeof(T), "x");
LambdaExpression expr;
if (ids.Count == 0)
{
expr = Expression.Lambda(LambdaExpression.Constant(false), x);
}
else
{
expr = Expression.Lambda(BuildEqual(x, ids.ToArray()), x);
}
return repo.Find<T>((Expression<Func<T,bool>>)expr).ToList();
}
private BinaryExpression BuildEqual(ParameterExpression x, int id)
{
MemberExpression left = Expression.Property(x, "Id");
ConstantExpression right = Expression.Constant(id);
return Expression.Equal(left, right);
}
private BinaryExpression BuildEqual(ParameterExpression x, int[] ids, int pos = 0)
{
int id = ids[pos];
pos++;
if (pos == ids.Length)
{
return BuildEqual(x, id);
}
return Expression.OrElse(BuildEqual(x, ids, pos), BuildEqual(x, id));
}
其他提示
亚音速可能无法转换 userIds.Contains
因为它无法将该列表转换为可以在SQL数据库上执行的内容。您可能必须求助于解释或条件:
repo.Find<User>(x => x.Id == 1 || x.Id == 3).ToList();
我敢肯定,如果您使用iEnumerable而不是列表,这将起作用。因此,以下内容应起作用:
SimpleRepository repo = new SimpleRepository("ConnectionString");
IEnumerable<int> userIds = new List<int>();
userIds.Add(1);
userIds.Add(3);
List<User> users = repo.Find<User>(x => userIds.Contains(x.Id)).ToList();
不隶属于 StackOverflow