从导航属性选择器字符串C#创建MemberExpression?

时间:2014-11-30 05:50:41

标签: c# linq expression

我们有以下实体:

public class Employee
{
    public int Serial { get; set; }
    public string FullName { get; set; }
    public Section Section { get; set; }
}

public class Section
{
    public int Serial { get; set; }
    public string SectionName { get; set; }
    public SupperSection SupperSection { get; set; }
    public ICollection<Employee> Sections { get; set; }
}

我们想从以下字符串创建MemberExpression

Employee.Section.SectionName 

我们这样做:

// selectorString = Section.SectionName
// we wanna create     entity => entity.Section.SectionName
ParameterExpression parameterExpression = Expression.Parameter(entityType, "entity");    
MemberExpression result = Expression.Property(parameterExpression, selectorString); // Exception

但它会引发以下异常:

  

未处理的类型&#39; System.ArgumentException&#39;发生在   System.Core.dll

     

其他信息:Property&#39; System.String SectionName&#39;未定义类型&#39; DtoContainer.Employee&#39;

我们怎么做?

2 个答案:

答案 0 :(得分:3)

您需要创建对象实例并构建表达式树,如下所示:

Employee employee = new Employee()
{
    Section = new Section() { SectionName = "test" }
};
MemberExpression sectionMember = Expression.Property(ConstantExpression.Constant(employee), "Section");
MemberExpression sectionNameMember = Expression.Property(sectionMember, "SectionName");

答案 1 :(得分:0)

var selectorString = "Employee.Section.SectionName";
var properties = selectorString.Split(".");
var property = Expression.Property(parameter, properties[0]);

//You can add like this 
property = properties.Skip(1).Aggregate(property, (current, propertyName) => Expression.Property(current, propertyName));

//or you use a shorter version by passing as a method group
property = properties.Skip(1).Aggregate(property, Expression.Property);


var expression = Expression.Lambda(typeof(Func<,>).MakeGenericType(typeof(TEntity), property.Type), property, parameter);