2

在 SubSonic 3.04 的 SimpleRepository 中,我似乎无法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”,但未定义

我在这里遗漏了什么,还是 SubSonic 不支持Containslambda 表达式?如果没有,这将如何完成?

4

3 回答 3

4

由于这些似乎都不起作用......

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));
}
于 2010-05-20T17:29:22.753 回答
0

Subsonic 可能无法转换,userIds.Contains因为它无法将该列表转换为可以在 SQL 数据库上执行的内容。您可能不得不求助于明确定义 or 条件:

repo.Find<User>(x => x.Id == 1 || x.Id == 3).ToList();
于 2010-05-20T17:07:10.420 回答
0

如果您使用 IEnumerable 而不是 List,我很确定这将起作用。所以以下应该工作:

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();
于 2010-05-20T19:15:04.730 回答