将属性名称作为字符串.NET传递给方法

时间:2011-01-17 12:06:10

标签: c# .net linq-to-sql reflection

我正在使用LINQ to SQL作为.NET MVC应用程序。

在我的数据库中,我有一堆列中含有“Y”或“N”值的列。

我正在尝试编写一个通用方法,它将返回数据库中columnName == 'Y'

的所有记录

到目前为止我已经有了这个

public IQueryable<Approved> ReturnRecordsByObjectiveFlag(string columnName)
{       
    return from approved in db.Approved
           where approved.GetType().GetProperties().Where(x => x.Name.Equals(columnName)).Equals("Y")
           select approved;
}

但是这给了我这个错误

  

'System.Reflection.MemberInfo'的成员访问'System.String Name'在类型'System.Reflection.PropertyInfo []上不合法。

知道我可能会出错吗?

谢谢。

5 个答案:

答案 0 :(得分:3)

public IQueryable<Approved> ReturnRecordsByObjectiveFlag(string columnName)
{   
    var param = Expression.Parameter(typeof(Approved), "x");
    var predicate = Expression.Lambda<Func<Approved,bool>>(
        Expression.Equal(
            Expression.PropertyOrField(param, columnName),
            Expression.Constant("Y")
        ), param);
    return db.Approved.Where(predicate);
}

编辑;如果属性实际为char?,即'Y'而非"Y",则:

public IQueryable<Approved> ReturnRecordsByObjectiveFlag(string columnName)
{
    var param = Expression.Parameter(typeof(Approved), "x");
    Expression prop;
    var predicate = Expression.Lambda<Func<Approved, bool>>(
        Expression.Equal(
            (prop = Expression.PropertyOrField(param, columnName)),
            Expression.Constant(prop.Type == typeof(string) ?
                (object)"Y" : (object)'Y', prop.Type)
        ), param);
    return db.Approved.Where(predicate);
}

(现在应对所有stringcharchar?

答案 1 :(得分:1)

出现问题的是您无法在LINQ查询中使用反射。

有多少列 - 它是一个固定的相对较小的数字?如果是这样,请使用switch语句在多个LINQ查询之间进行选择。这更清洁,更快。

如果它是大量列,或者它们是动态的,您可以构造一个动态SQL语句,但要小心检查可能的注入攻击。

答案 2 :(得分:1)

approved.GetType().GetProperties()

将返回PropertyInfo []对象。即使使用Where过滤它仍然不是属性的值,它基本上是满足批评的属性集合,即使该集合只有一个成员。

要按名称获取特定属性,最好使用Type类的GetProperty()方法,如下所示:

PropertyInfo pi = approved.GetType().GetProperty(columnName);

但是,你还没有完成。您仍然必须按属性的值过滤对象,这是通过在属性上使用GetValue()方法完成的,如下所示:

bool isApproved = pi.GetValue(approved, null).Equals("Y");

或将所有内容放在您的上下文中:

return from approved in db.Approved
where approved.GetType().GetProperty(columnName)
                     .GetValue(approved, null).Equals("Y")
select approved;

答案 3 :(得分:0)

  • GetType()返回Type

  • GetProperties()返回PropertyInfo[]

  • Where(..)返回IEnumerable<PropertyInfo>

所以你打电话

IEnumerable<PropertyInfo>.Equals(string)

这似乎是错误的。不是吗?

答案 4 :(得分:-2)

这是因为最后一个Equals方法在过滤的IQueryable集合上运行,而不是在属性值本身上运行。

请改为尝试:

return from approved in db.Approved
               where approved.GetType().GetProperties().Where(x => x.Name.Equals(columnName) && (string)x.GetValue(db.Approved, null) == "Y")
               select approved;