在我关于制定IQueryable来查询递归数据库表的问题之后,我尝试了给出的答案,并更接近我的问题的解决方案。我已经重组了提供的答案,因此对我来说更容易理解正在发生的事情。但是,无论我尝试什么,我都会不断收到错误消息"the parameter 'x' is not in scope"
在线return entities.Single();
。如何确保参数"x"在 IN 范围内?我尝试过在BuildParentPropertiesExpression
方法中制作ParameterExpression
,我尝试每次都用不同的名称将其放入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;
}
你与原始实现非常接近
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();
}