动态linq表达式查询,得到问题

时间:2011-11-07 06:53:01

标签: c# linq entity-framework-4 expression

我试图根据需要在查询中加入4个表。因为我想在where子句中动态添加条件,所以我现在可以为2表查询执行此操作。但这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");

这适用于2表连接而不是更多。因为在复杂查询中它生成Annonymouse对象。所以 那么我需要通过什么代替“??????”分数...?通常需要将属性名称作为“agr.AgreementId”传递,但这里它将扩展类中的表达式为“Value Canot be Null:propertyName”。 需要更多指导...

2 个答案:

答案 0 :(得分:5)

我认为您可能想要考虑(作为额外的重载):

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 :(得分:1)

你最好去predicate builder i.e Dynamically Composing Expression Predicates 它允许您轻松地动态构建查询。