【问题标题】:Access property in lambda expression from string when using LINQ使用 LINQ 时从字符串访问 lambda 表达式中的属性
【发布时间】:2011-08-10 20:23:25
【问题描述】:

我该如何做这样的事情:

var 结果 = db.MyTable.Where(x => x."MyProperty" == "Test" );

如您所见,我想访问“MyProperty”,但将属性名称作为字符串。

【问题讨论】:

标签: c# string linq lambda properties


【解决方案1】:

你可以使用反射

x.GetType( ).GetProperty("MyProperty").GetValue( x, null ); 

虽然这可能有效,但我不建议这样做,为什么不将 where 子句作为表达式传递:

myMethod<T>(Expression<Func<T,bool>> where)

评论后的例子:

考虑以下类型:

您会看到三个属性,其中名称是字符串类型,id 是 int 类型。现在,如果我们将数据库上下文包装在这样的服务中

public class MyTypeOfXService
{
    private DataDataContext Context;
    public MyTypeOfXService()
    {
        Context = new DataDataContext("example code");
    }

    public IQueryable<MyTypeOfX> GetTypeOfX(Expression<Func<MyTypeOfX, bool>> where)
    {
        return this.Context.MyTypeOfXes.Where(where);
    }
}

在我们的 get 方法中有一个 Expression 参数,它接受两个泛型,第一个是我们的类型 x,第二个是布尔值。这种方法的优点是我们可以抽象所有的数据上下文创建并且只在我们的代码中表达一个 where 子句参见最后一段代码:

class Program
{
    static void Main(string[] args)
    {
        var service = new MyTypeOfXService();

        var queryById = service.GetTypeOfX((mytype) => mytype.Id == 1);
        var queryByName = service.GetTypeOfX((mytype) => mytype.Name == "MyName");
        var queryByName = service.GetTypeOfX((mytype) => mytype.Name == "MyName" && mytype.Id == 1);
    }
}

如您所见,我们可以在任何属性或属性组合上构建 where 子句。

【讨论】:

  • 我正在使用 Linq To SQL,因此 GetProperty() 不起作用。如何用表达式做到这一点?
  • 我给你举个例子,给我15分钟。
【解决方案2】:

我想你可以试试这个:

public static IQueryable<T> SortByPropertyName<T>(this IQueryable<T> queryable, string orderFieldName) where T : Entity
{
    var param = Expression.Parameter(typeof(T), typeof(T).Name);
    var orderExpression = Expression.Lambda<Func<T, object>>(Expression.Property(param, orderFieldName), param);
    return queryable.OrderBy(orderExpression);
}

它适用于订单。

【讨论】:

    【解决方案3】:

    我不知道 x 是如何实现的,但是如果 x 有一个索引器,那么您可以像这样制定您的查询:

    var result = db.MyTable.Where(x => x["MyProperty"] == "Test" );
    

    请参阅http://msdn.microsoft.com/en-us/library/6x16t2tx.aspx 以了解 c# 中的索引器

    【讨论】:

      【解决方案4】:

      除非您直接使用 LINQ to SQL 查询数据库,否则您可以使用反射来获取它。

      以下是如何使用反射获取属性信息的示例:

      class Program
      {
          class Person
          {
              public string FirstName { get; set; }
              public string LastName { get; set; }
              public byte Age { get; set; }
              public override string ToString()
              {
                  return string.Format("{0}, {1} ({2})", LastName, FirstName, Age);
              }
          }
      
          static void Main(string[] args)
          {
              Person p1 = new Person() { FirstName = "Bill", LastName = "Johnson", Age = 34 };
              Person p2 = new Person() { FirstName = "Sally", LastName = "Jones", Age = 21 };
              Person p3 = new Person() { FirstName = "Jame", LastName = "Smith", Age = 28 };
      
              List<Person> people = new List<Person>(new Person[] { p1, p2, p3 });
      
              IEnumerable<Person> foundPeople = people.Where(p => p.GetType().GetProperty("LastName").GetValue(p,null).ToString().StartsWith("J"));
      
              foreach (Person person in foundPeople)
              {
                  Console.WriteLine(person.ToString());
              }
              Console.ReadKey();
          }
      }
      

      请小心,因为如果您查询大量数据,这可能会导致性能问题。

      【讨论】:

        猜你喜欢
        • 2016-07-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-12
        • 2017-03-21
        • 1970-01-01
        • 2016-04-18
        • 1970-01-01
        相关资源
        最近更新 更多