再帰的なデータベース テーブルをクエリするための IQueryable の定式化に関する私の質問に続いて、与えられた答えを試し、私の問題の解決策にかなり近づきました。提供された回答を再構築したので、何が起こっているのかを理解しやすくなりました。ただし、何をしようとしても"the parameter 'x' is not in scope"
、行にエラーメッセージが表示され続けますreturn entities.Single();
。パラメータ「x」がスコープ内にあることを確認するにはどうすればよいですか? ParameterExpression
をメソッド内に作ってみBuildParentPropertiesExpression
たり、毎回別の名前で 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;
}