linq表达式树多对多IQueryable扩展名

问题描述 投票:1回答:2

我目前在asp.net Web API 2应用程序上工作。请记住我的经验是在php,js,css等方面,而不是c#。

希望有人可以帮助我使用Linq Expressions树的通用IQueryable扩展。

我有3个表(实体框架)。

交易

Id,Name

产品贸易(链接表)

Id,Trade_Id,Product_Id

产品

Id,Code

我需要从作为变量传递的产品代码列表中返回至少具有一个产品代码的所有交易

我在以下方面工作正常

list<string> tocheck = new list<string>("productcode1","productcode2");
var trades = db.Trades.SqlQuery(
               "Select * from Trades T " +
               "left join ProductTrades PT on T.Id = PT.Trade_Id " +
               "left join Products P on PT.Product_Id = P.Id " +
               "where P.Code in (@prod)", new SqlParameter("@prod", String.Join(",", tocheck))).ToList();

但是我想使用Linq表达式树来实现这一点,使其变得通用

请参见下文,我的尝试(我在尝试学习时已使用多种资源将其放在一起)

public static IQueryable<T> FilterWhereItemIn<T>(this IQueryable<T> queryable, string propertyOrFieldName, List<string> values)
        {
            var elementType = typeof(T);
            var parameterExpression = Expression.Parameter(elementType);
            var propertyOrFieldExpression = propertyOrFieldName.Split('.').Aggregate((Expression)parameterExpression, Expression.PropertyOrField);
            var method = typeof(List<string>).GetMethod("Contains", new Type[] { typeof(string) });
            var someValue = Expression.Constant(values, typeof(List<string>));
            var containsExpression = Expression.Call(propertyOrFieldExpression, method, someValue);
            var selector = Expression.Lambda<Func<T, bool>>(containsExpression, parameterExpression);
            return queryable.Where(selector);
        }

并且我将其称为(IQueryable queryable是交易类型)

list<string> tocheck = new list<string>("productcode1","productcode2");
queryable.FilterWhereItemIn("Products.Code", tocheck );

但是我收到“代码”不存在的错误消息。我认为这是因为产品是一个集合。有谁知道如何实现这一目标。

(对不起,这篇文章有点匆忙)

entity-framework asp.net-web-api2 iqueryable linq-expressions
2个回答
0
投票

您混合了Expression.Call行中的参数。您应该针对列表而不是属性调用Contains方法。改用它:

var containsExpression = Expression.Call(someValue, method, propertyOrFieldExpression);

0
投票

[与DavidG讨论(谢谢)后,看来我在实现目标时走了错误的路。

不需要我进行扩展,我可以使用简单的一行linq查询来获得所需的结果。

var trades = new List<Trade>();
trades = db.Trades.Where(t => t.Products.Any(p => getRequest.products.Contains(p.Code))).ToList();

[getRequest只是一个简单的类,具有public list<string> products { get; set; } getter和setter

© www.soinside.com 2019 - 2024. All rights reserved.