动态 linq 表达式查询,出现问题

发布于 2024-12-13 19:00:53 字数 1578 浏览 0 评论 0原文

我尝试根据要求在查询中连接 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);
        }
    }

// 我添加 where 条件的代码:

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 Cannot be Null : propertyName”表达式。 需要更多指导...

I an tryin to join 4 tables within a query as per requirement. where as I wanted to add the conditions in where clause dynamically so, i could able to do this for 2 table query as of now. but this 4 table join is bit the complex join here. To extend the functionality i am using following code to add dynamic where clause :

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

//
My code to add where conditions:

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

This is working for 2 table join not for more than that. because within complex query it is generating the Annonymouse object. so
so what should i need to pass in place of "??????" marks...? typically need to pass the property name as"agr.AgreementId" but here it is throwing the expression as "Value Canot be Null : propertyName" in extension class.
Need more guidance for this ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我做我的改变 2024-12-20 19:00:54

最好使用谓词构建器,即动态组合表达式谓词
这使您可以轻松地动态构建查询。

It's better you go for the predicate builder i.e Dynamically Composing Expression Predicates
which allows you to build query dynamically easily.

愁杀 2024-12-20 19:00:53

我认为您可能需要考虑类似的东西(作为额外的重载):

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

I think you might want to consider something like (as an additional overload):

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

and using:

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

however! it is much easier to use just:

agrs = agrs.Where(x => x.agr.AgreementId ==
             "A83C82C5-F9D6-4833-A234-EBB5D971280C");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文