gpt4 book ai didi

c# - Entity Framework Core - 使用以接口(interface)作为参数的表达式树

转载 作者:行者123 更新时间:2023-11-30 22:56:10 25 4
gpt4 key购买 nike

对于以下场景,我将非常感谢您的帮助。我有以下类(class):

public class Product : IHasPrice
{
public string Title { get; set; }
public int Price { get; set; }
public string CustomerId { get; set; }

}

public interface IHasPrice
{
int Price { get; set; }
}

public class ProductProvider
{
public ProductProvider()
{
}

public IEnumerable<Product> GetByCustomer(string customerId, Expression<Func<IHasPrice, bool>> predicate = null)
{
using (var db = new ApplicationDbContext())
{
var queryable = db.Products.Where(p => p.CustomerId == customerId);
if (predicate != null)
{
return queryable.Where(predicate).ToList();
}
else
{
return queryable.ToList();
}
}
}
}

我想启用 ProductProvider 的使用方式,您只能按客户选择,但您也可以按您喜欢的任何方式(并且仅按价格)过滤价格。此示例不起作用,因为 queryable.Where 需要类型为 Expression(Func(Product, bool)) 的参数。有没有办法做到这一点,或者我必须在过滤价格之前将数据提取到内存中?

最佳答案

IQueryable<out T>接口(interface)是协变的,传递的lambda表达式可以直接与Where一起使用方法:

var query = queryable.Where(predicate);

唯一的问题是现在结果查询的类型是IQueryable<IHasPrice> .你可以把它转回IQueryable<Product>使用 Queryable.Cast方法:

var query = db.Products.Where(p => p.CustomerId == customerId);
if (predicate != null)
query = query.Where(predicate).Cast<Product>(); // <--
return query.ToList();

测试并使用最新的 EF Core 2.2(在某些早期版本中可能会失败)。


另一种解决方案是转换 Expression<Func<IHasPrice, bool>>到预期的Expression<Func<Product, bool>>通过“调用”它:

var query = db.Products.Where(p => p.CustomerId == customerId);
if (predicate != null)
{
var parameter = Expression.Parameter(typeof(Product), "p");
var body = Expression.Invoke(predicate, parameter);
var newPredicate = Expression.Lambda<Func<Product, bool>>(body, parameter);
query = query.Where(newPredicate);
}
return query.ToList();

关于c# - Entity Framework Core - 使用以接口(interface)作为参数的表达式树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54626624/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com