5

How can I do something like this:

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

As you can see I want to access "MyProperty" but give the property name as a sting.

NKnusperer
  • 974
  • 1
  • 11
  • 31
  • 3
    see Dynamic Linq: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx – BrokenGlass Aug 10 '11 at 20:25
  • 1
    possible duplicate of [Dynamic LINQ on IEnumerable?](http://stackoverflow.com/questions/485895/dynamic-linq-on-ienumerable) – Craig Stuntz Aug 10 '11 at 20:30

4 Answers4

7

You could use reflection

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

although this might work, i wouldn't advise on doing this, why don't pass in your where clause as an expression like:

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

example after comment:

consider the following type:

you see there are three properties where the name is of type string and id is of type int. now if we wrap our database context in a service like this

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);
    }
}

in our get method there is an Expression parameter that takes two generics, the first is our type x and the second is a boolean. The advantage of this approach is that we can abstract all the data context creation and only express an where clause in our code see final piece of code:

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);
    }
}

as you can see, we can build a where clause on any property or combination of properties.

Refugee
  • 483
  • 1
  • 3
  • 13
Didier Caron
  • 570
  • 3
  • 9
4

I think you can try this:

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);
}

It works fine for order.

huysentruitw
  • 27,376
  • 9
  • 90
  • 133
Sts
  • 49
  • 4
0

I don't know how x is implemented, but if x has an indexer, then you could formulate your query like:

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

see http://msdn.microsoft.com/en-us/library/6x16t2tx.aspx for indexers in c#

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
0

You can use reflection to get it unless you are querying a database directly using LINQ to SQL.

Here is a sample of how to get property info using reflection:

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();
    }
}

Just be careful because this could lead to performance issues if you are querying a large amount data.

Dave
  • 860
  • 7
  • 18