динамическое выражение linq для запроса, получение проблемы - PullRequest
2 голосов
/ 07 ноября 2011

Я пытаюсь объединить 4 таблицы в запросе согласно требованию.где, поскольку я хотел динамически добавлять условия в условие where, я мог сделать это для запроса к двум таблицам на данный момент.но это соединение за 4 столами немного сложнее.Чтобы расширить функциональность, я использую следующий код для добавления динамического предложения where:

public static class Extensions
    {
        public static IQueryable<T> AddEqualityCondition<T, V>(this IQueryable<T> queryable,
          string propertyName, V propertyValue)
        {
            ParameterExpression pe = Expression.Parameter(typeof(T), "p");

   IQueryable<T> x = queryable.Where<T>(Expression.Lambda<Func<T, bool>>(Expression.Equal(Expression.Property(pe, typeof(T).GetProperty(propertyName)), Expression.Constant(propertyValue, typeof(V)), false, typeof(T).GetMethod("op_Equality")), new ParameterExpression[] { pe }));
            return (x);
        }
    }

// Мой код для добавления в условиях:

Query is:
 var agrs = (from agr in _dbContext.Agreements
                                 join amdv in _dbContext.AgreementMetaDataValues on agr.AgreementID equals amdv.AgreementID 
                                 join emd in _dbContext.EntityMetadatas on amdv.AttributeId equals emd.AttributeId
                                 join et in _dbContext.Entities on agr.EntityID equals et.EntityId
                                 select new  agr, amdv,emd });

//Add dynamically where conditions:
 agrs = agrs.AddEqualityCondition("?????", "A83C82C5-F9D6-4833-A234-EBB5D971280C");

Это работает для объединения двух таблиц, а недля чего-то большего.потому что в сложном запросе он генерирует объект Annonymouse.так что же мне нужно передать вместо "??????"Метки...?обычно необходимо передать имя свойства как «agr.AgreementId», но здесь оно выдает выражение «Значение не может быть пустым: propertyName» в классе расширения.Нужно больше руководства для этого ...

Ответы [ 2 ]

5 голосов
/ 07 ноября 2011

Я думаю, что вы можете рассмотреть что-то вроде (в качестве дополнительной перегрузки):

public static IQueryable<T> AddEqualityCondition<T, V>(
    this IQueryable<T> queryable,
    Expression<Func<T, V>> selector, V propertyValue)
{
    var lambda = Expression.Lambda<Func<T,bool>>(
       Expression.Equal(
           selector.Body,
           Expression.Constant(propertyValue, typeof(V)),
           false, typeof(T).GetMethod("op_Equality")),
        selector.Parameters);
    return queryable.Where(lambda);           
}

и использование:

agrs = agrs.AddEqualityCondition(x => x.agr.AgreementId, 
             "A83C82C5-F9D6-4833-A234-EBB5D971280C");

однако!Гораздо проще использовать просто:

agrs = agrs.Where(x => x.agr.AgreementId ==
             "A83C82C5-F9D6-4833-A234-EBB5D971280C");
1 голос
/ 07 ноября 2011

Лучше использовать построитель предикатов , то есть динамически составлять предикаты выражений , которые позволяют легко динамически создавать запросы.

...