Доступ к свойству в лямбда-выражении из строки при использовании LINQ - PullRequest
2 голосов
/ 11 августа 2011

Как я могу сделать что-то вроде этого:

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

Как вы можете видеть, я хочу получить доступ к "MyProperty", но дать имя свойства в виде строки.

Ответы [ 4 ]

4 голосов
/ 11 августа 2011

Вы можете использовать отражение

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

, хотя это может сработать, я бы не советовал делать это, почему бы не передать выражение where в качестве выражения типа:

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

пример после комментария:

рассмотрим следующий тип:

вы видите три свойства, где имя имеет тип string, а 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на любую собственность или комбинацию свойств.

3 голосов
/ 18 июля 2013

Я думаю, вы можете попробовать это:

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

Работает отлично под заказ.

0 голосов
/ 11 августа 2011

Вы можете использовать отражение, чтобы получить его, если вы не запрашиваете базу данных напрямую, используя 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();
    }
}

Просто будьте осторожны, так как это может привести к проблемам с производительностью, если вы запрашиваете большой объем данных.

0 голосов
/ 11 августа 2011

Я не знаю, как реализован x, но если x имеет индексатор, вы можете сформулировать свой запрос следующим образом:

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

см. http://msdn.microsoft.com/en-us/library/6x16t2tx.aspx для индексаторов в c #

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...