0

在我关于制定IQueryable 来查询递归数据库表的问题之后,我尝试了给出的答案,并且更接近我的问题的解决方案。我已经重组了提供的答案,所以对我来说更容易理解发生了什么。但是,无论我尝试什么,我都会不断收到错误消息"the parameter 'x' is not in scope"return entities.Single();如何确保参数“x”在范围内?我试过ParameterExpressionBuildParentPropertiesExpression方法中制作,我试过每次都用不同的名字把它放在for循环中。一切都无济于事。

在此处阅读背景故事

public Entity Single(string path)
{
    if (path[0] == '/')
        path = path.Substring(1); // only absolute paths for now

    List<string> pathParts = path.Split('/').ToList();
    pathParts.Reverse();

    var entities =
        from entity in dataContext.Entities
        select entity;

    // Build up a template expression that will be used to create the real expressions with.
    Expression<Func<Entity, bool>> templateExpression = (x => x.Code == "dummy");
    BinaryExpression equals = (BinaryExpression)templateExpression.Body;
    MemberExpression property = (MemberExpression)equals.Left;

    ParameterExpression entityParameter = Expression.Parameter(typeof(Entity), "x");

    for (int index = 0; index < pathParts.Count; index++)
    {
        string pathPart = pathParts[index];

        Expression parentPropertyExpression = BuildParentPropertiesExpression(index, entityParameter);

        MemberExpression left = Expression.Property(
            parentPropertyExpression,
            (PropertyInfo)property.Member
        );

        ConstantExpression right = Expression.Constant(pathPart);

        BinaryExpression equalExpression = Expression.Equal(
            left, 
            right, 
            equals.IsLiftedToNull, 
            equals.Method
        );

        var entityFilterExpression = Expression.Lambda<Func<Entity, bool>>(
            equalExpression, 
            templateExpression.Parameters
        );

        entities = entities.Where<Entity>(entityFilterExpression);
    }

    return entities.Single();
}

private Expression BuildParentPropertiesExpression(int numberOfParents, ParameterExpression entityParameter)
{
    if (numberOfParents == 0)
        return entityParameter;

    var getParentMethod = typeof(Entity).GetProperty("Entity1").GetGetMethod();
    var property = Expression.Property(entityParameter, getParentMethod);

    for (int count = 2; count <= numberOfParents; count++)
        property = Expression.Property(property, getParentMethod);

    return property;
}
4

1 回答 1

0

您与原始实现非常接近

public Entity Single(string path) {
    string[] pathParts = path.Split('/');
    string code = pathParts[pathParts.Length -1];

    if (pathParts.Length == 1)
            return dataContext.Entities.Single(e => e.Code == code && e.ParentID == 0);

    IQueryable<Entity> entities = dataContext.Entities.Where(e => e.Code == code);
    for (int i = pathParts.Length - 2; i >= 0; i--) {
        string parentCode = pathParts[i];
        entities = entities.Where(e => e.Entity1.Code == parentCode).Select(e => e.Entity1); //This now gets the parent entity
    }

    return entities.Single();
}
于 2012-11-20T20:29:00.447 回答