Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将表达式树与任何EntityCore一起使用_C#_Linq_Entity Framework Core - Fatal编程技术网

C# 将表达式树与任何EntityCore一起使用

C# 将表达式树与任何EntityCore一起使用,c#,linq,entity-framework-core,C#,Linq,Entity Framework Core,我正在尝试筛选具有属性的实体对象(另一个实体,嵌套) 我想返回作为实体的父对象,但我想用一组表达式对所有属性进行过滤,从而得到for循环 目前它还没有完成,会永远运行吗 问题是我需要在WHERE内部执行任何操作 IQueryable<Product> entity = _context.Products.AsNoTracking() .Include(e => e.Attributes) .ThenInclude(e => e.Attribute.Pare

我正在尝试筛选具有属性的实体对象(另一个实体,嵌套)

我想返回作为实体的父对象,但我想用一组表达式对所有属性进行过滤,从而得到for循环

目前它还没有完成,会永远运行吗

问题是我需要在WHERE内部执行任何操作

IQueryable<Product> entity = _context.Products.AsNoTracking()
    .Include(e => e.Attributes)
    .ThenInclude(e => e.Attribute.ParentAttribute)
    .Include(e => e.Prices);

foreach (var rule in filter.ToRuleGroup().Rules)
{
    var compiled = Rule.CompileRule<ProductAttribute>(rule);
    entity = entity.Where(x => x.Attributes.Any(y => compiled(y.Attribute)));
}

return entity.Take(10).ToArray(); 
问题是这仍然需要很长时间。我没有得到回应。 以下是来自实体的SQL:

    SELECT [p].[Id], [p].[IsActive], [p].[IsSyncEnabled], [p].[IsSyncQueued], [p].[LastModifiedDate], [p].[MID], [p].[Sku], [p].[SkuId]
FROM [Product] AS [p]
WHERE (((EXISTS (
    SELECT 1
    FROM [Product_ProductAttribute] AS [a]
    INNER JOIN [Product_Attribute] AS [a.Attribute] ON [a].[AttributeId] = [a.Attribute].[Id]
    WHERE ([a.Attribute].[Type] = N'Raw Sku') AND ([p].[Id] = [a].[ProductId])) AND EXISTS (
    SELECT 1
    FROM [Product_ProductAttribute] AS [a0]
    INNER JOIN [Product_Attribute] AS [a.Attribute0] ON [a0].[AttributeId] = [a.Attribute0].[Id]
    WHERE ([a.Attribute0].[Name] = N'SMALL') AND ([p].[Id] = [a0].[ProductId]))) AND EXISTS (
    SELECT 1
    FROM [Product_ProductAttribute] AS [a1]
    INNER JOIN [Product_Attribute] AS [a.Attribute1] ON [a1].[AttributeId] = [a.Attribute1].[Id]
    WHERE ([a.Attribute1].[Type] = N'Raw Sku') AND ([p].[Id] = [a1].[ProductId]))) AND EXISTS (
    SELECT 1
    FROM [Product_ProductAttribute] AS [a2]
    INNER JOIN [Product_Attribute] AS [a.Attribute2] ON [a2].[AttributeId] = [a.Attribute2].[Id]
    WHERE ([a.Attribute2].[Name] = N'LARGE') AND ([p].[Id] = [a2].[ProductId]))) AND EXISTS (
    SELECT 1
    FROM [Product_ProductAttribute] AS [a3]
    INNER JOIN [Product_Attribute] AS [a.Attribute3] ON [a3].[AttributeId] = [a.Attribute3].[Id]
    WHERE ([a.Attribute3].[Name] = N'BLACK') AND ([p].[Id] = [a3].[ProductId]))
ORDER BY [p].[Id]
Microsoft.EntityFrameworkCore.Database.Command:Information: Executed DbCommand (93ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [p.Attributes].[Id], [p.Attributes].[AttributeId], [p.Attributes].[ProductId], [p.Attribute].[Id], [p.Attribute].[Hiearchy], [p.Attribute].[Name], [p.Attribute].[ParentAttributeId], [p.Attribute].[Type], [p.Attribute].[Value], [p.Attribute.ParentAttribute].[Id], [p.Attribute.ParentAttribute].[Hiearchy], [p.Attribute.ParentAttribute].[Name], [p.Attribute.ParentAttribute].[ParentAttributeId], [p.Attribute.ParentAttribute].[Type], [p.Attribute.ParentAttribute].[Value]
FROM [Product_ProductAttribute] AS [p.Attributes]
INNER JOIN [Product_Attribute] AS [p.Attribute] ON [p.Attributes].[AttributeId] = [p.Attribute].[Id]
LEFT JOIN [Product_Attribute] AS [p.Attribute.ParentAttribute] ON [p.Attribute].[ParentAttributeId] = [p.Attribute.ParentAttribute].[Id]
INNER JOIN (
    SELECT [p0].[Id]
    FROM [Product] AS [p0]
    WHERE (((EXISTS (
        SELECT 1
        FROM [Product_ProductAttribute] AS [a4]
        INNER JOIN [Product_Attribute] AS [a.Attribute4] ON [a4].[AttributeId] = [a.Attribute4].[Id]
        WHERE ([a.Attribute4].[Type] = N'Raw Sku') AND ([p0].[Id] = [a4].[ProductId])) AND EXISTS (
        SELECT 1
        FROM [Product_ProductAttribute] AS [a5]
        INNER JOIN [Product_Attribute] AS [a.Attribute5] ON [a5].[AttributeId] = [a.Attribute5].[Id]
        WHERE ([a.Attribute5].[Name] = N'SMALL') AND ([p0].[Id] = [a5].[ProductId]))) AND EXISTS (
        SELECT 1
        FROM [Product_ProductAttribute] AS [a6]
        INNER JOIN [Product_Attribute] AS [a.Attribute6] ON [a6].[AttributeId] = [a.Attribute6].[Id]
        WHERE ([a.Attribute6].[Type] = N'Raw Sku') AND ([p0].[Id] = [a6].[ProductId]))) AND EXISTS (
        SELECT 1
        FROM [Product_ProductAttribute] AS [a7]
        INNER JOIN [Product_Attribute] AS [a.Attribute7] ON [a7].[AttributeId] = [a.Attribute7].[Id]
        WHERE ([a.Attribute7].[Name] = N'LARGE') AND ([p0].[Id] = [a7].[ProductId]))) AND EXISTS (
        SELECT 1
        FROM [Product_ProductAttribute] AS [a8]
        INNER JOIN [Product_Attribute] AS [a.Attribute8] ON [a8].[AttributeId] = [a.Attribute8].[Id]
        WHERE ([a.Attribute8].[Name] = N'BLACK') AND ([p0].[Id] = [a8].[ProductId]))
) AS [t] ON [p.Attributes].[ProductId] = [t].[Id]
ORDER BY [t].[Id]
Microsoft.EntityFrameworkCore.Database.Command:Information: Executed DbCommand (156ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [p.Prices].[Division], [p.Prices].[ProductId], [p.Prices].[PriceId], [p.Prices].[EntryDate], [p.Prices].[EffectiveDate], [p.Prices].[ExpireDate]
FROM [Product_ProductPrice] AS [p.Prices]
INNER JOIN (
    SELECT [p1].[Id]
    FROM [Product] AS [p1]
    WHERE (((EXISTS (
        SELECT 1
        FROM [Product_ProductAttribute] AS [a9]
        INNER JOIN [Product_Attribute] AS [a.Attribute9] ON [a9].[AttributeId] = [a.Attribute9].[Id]
        WHERE ([a.Attribute9].[Type] = N'Raw Sku') AND ([p1].[Id] = [a9].[ProductId])) AND EXISTS (
        SELECT 1
        FROM [Product_ProductAttribute] AS [a10]
        INNER JOIN [Product_Attribute] AS [a.Attribute10] ON [a10].[AttributeId] = [a.Attribute10].[Id]
        WHERE ([a.Attribute10].[Name] = N'SMALL') AND ([p1].[Id] = [a10].[ProductId]))) AND EXISTS (
        SELECT 1
        FROM [Product_ProductAttribute] AS [a11]
        INNER JOIN [Product_Attribute] AS [a.Attribute11] ON [a11].[AttributeId] = [a.Attribute11].[Id]
        WHERE ([a.Attribute11].[Type] = N'Raw Sku') AND ([p1].[Id] = [a11].[ProductId]))) AND EXISTS (
        SELECT 1
        FROM [Product_ProductAttribute] AS [a12]
        INNER JOIN [Product_Attribute] AS [a.Attribute12] ON [a12].[AttributeId] = [a.Attribute12].[Id]
        WHERE ([a.Attribute12].[Name] = N'LARGE') AND ([p1].[Id] = [a12].[ProductId]))) AND EXISTS (
        SELECT 1
        FROM [Product_ProductAttribute] AS [a13]
        INNER JOIN [Product_Attribute] AS [a.Attribute13] ON [a13].[AttributeId] = [a.Attribute13].[Id]
        WHERE ([a.Attribute13].[Name] = N'BLACK') AND ([p1].[Id] = [a13].[ProductId]))
) AS [t0] ON [p.Prices].[ProductId] = [t0].[Id]
ORDER BY [t0].[Id]
不要在查询表达式树中使用委托(
Func
),因为它们会导致。在您的情况下,应该使用
表达式ToWhere(Rule r)
(考虑更改名称),而不是
Func编译器(Rule r)

为了能够将
表达式
用于
可枚举。任何需要
Func
并应用于表达式树内部集合访问器的
,您需要这样的帮助器方法:

public static partial class ExpressionUtils
{
    public static Expression<Func<TOuter, bool>> Any<TOuter, TInner>(Expression<Func<TOuter, IEnumerable<TInner>>> innerSelector, Expression<Func<TInner, bool>> innerPredicate)
    {
        var parameter = innerSelector.Parameters[0];
        var body = Expression.Call(
            typeof(Enumerable), nameof(Enumerable.Any), new[] { typeof(TInner) },
            innerSelector.Body, innerPredicate);
        return Expression.Lambda<Func<TOuter, bool>>(body, parameter);
    }
}
您的样本的用法如下:

foreach (var rule in filter.ToRuleGroup().Rules)
{
    entity = entity.Where(Rule.Any((Product p) => p.Attributes.Select(a => a.Attribute), rule));
}

中使用compiled(
Func
)将导致EF Core在内存中执行过滤-您的产品表有多大?您应该使用
表达式.Lambda
,这样查询将在db引擎上过滤。@NetMage我如何将lamda称为任何(y=>uncompiled(y.Attribute))?引用我在别处写的一个答案,
表达式
处理会像疾病一样向外传播。您需要创建一个
表达式.Lambda
来表示传入
Where
方法的内容。嘿,谢谢!我仍然没有收到响应,并且运行查询的时间太长。从日志输出来看,这两个SQL查询似乎执行正确(分别为93ms和156ms)。之后可能会出现序列化问题。替换
返回实体.Take(10).ToArray()带有
var result=entity.Take(10.ToArray();返回结果
,在
返回结果上设置断点行,并查看它被命中以及执行前一行所需的时间。如果在合理的时间内命中,请检查序列化选项,特别是引用循环处理。它命中数组并返回,但webapi没有正确序列化。。。尽管我有services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2).AddJsonOptions(options=>{options.SerializerSettings.ReferenceLoopHandling=Newtonsoft.Json.ReferenceLoopHandling.Ignore;});Nvm多对多错误。。。在json中,我需要手动忽略它。多亏了伊万!
    SELECT [p].[Id], [p].[IsActive], [p].[IsSyncEnabled], [p].[IsSyncQueued], [p].[LastModifiedDate], [p].[MID], [p].[Sku], [p].[SkuId]
FROM [Product] AS [p]
WHERE (((EXISTS (
    SELECT 1
    FROM [Product_ProductAttribute] AS [a]
    INNER JOIN [Product_Attribute] AS [a.Attribute] ON [a].[AttributeId] = [a.Attribute].[Id]
    WHERE ([a.Attribute].[Type] = N'Raw Sku') AND ([p].[Id] = [a].[ProductId])) AND EXISTS (
    SELECT 1
    FROM [Product_ProductAttribute] AS [a0]
    INNER JOIN [Product_Attribute] AS [a.Attribute0] ON [a0].[AttributeId] = [a.Attribute0].[Id]
    WHERE ([a.Attribute0].[Name] = N'SMALL') AND ([p].[Id] = [a0].[ProductId]))) AND EXISTS (
    SELECT 1
    FROM [Product_ProductAttribute] AS [a1]
    INNER JOIN [Product_Attribute] AS [a.Attribute1] ON [a1].[AttributeId] = [a.Attribute1].[Id]
    WHERE ([a.Attribute1].[Type] = N'Raw Sku') AND ([p].[Id] = [a1].[ProductId]))) AND EXISTS (
    SELECT 1
    FROM [Product_ProductAttribute] AS [a2]
    INNER JOIN [Product_Attribute] AS [a.Attribute2] ON [a2].[AttributeId] = [a.Attribute2].[Id]
    WHERE ([a.Attribute2].[Name] = N'LARGE') AND ([p].[Id] = [a2].[ProductId]))) AND EXISTS (
    SELECT 1
    FROM [Product_ProductAttribute] AS [a3]
    INNER JOIN [Product_Attribute] AS [a.Attribute3] ON [a3].[AttributeId] = [a.Attribute3].[Id]
    WHERE ([a.Attribute3].[Name] = N'BLACK') AND ([p].[Id] = [a3].[ProductId]))
ORDER BY [p].[Id]
Microsoft.EntityFrameworkCore.Database.Command:Information: Executed DbCommand (93ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [p.Attributes].[Id], [p.Attributes].[AttributeId], [p.Attributes].[ProductId], [p.Attribute].[Id], [p.Attribute].[Hiearchy], [p.Attribute].[Name], [p.Attribute].[ParentAttributeId], [p.Attribute].[Type], [p.Attribute].[Value], [p.Attribute.ParentAttribute].[Id], [p.Attribute.ParentAttribute].[Hiearchy], [p.Attribute.ParentAttribute].[Name], [p.Attribute.ParentAttribute].[ParentAttributeId], [p.Attribute.ParentAttribute].[Type], [p.Attribute.ParentAttribute].[Value]
FROM [Product_ProductAttribute] AS [p.Attributes]
INNER JOIN [Product_Attribute] AS [p.Attribute] ON [p.Attributes].[AttributeId] = [p.Attribute].[Id]
LEFT JOIN [Product_Attribute] AS [p.Attribute.ParentAttribute] ON [p.Attribute].[ParentAttributeId] = [p.Attribute.ParentAttribute].[Id]
INNER JOIN (
    SELECT [p0].[Id]
    FROM [Product] AS [p0]
    WHERE (((EXISTS (
        SELECT 1
        FROM [Product_ProductAttribute] AS [a4]
        INNER JOIN [Product_Attribute] AS [a.Attribute4] ON [a4].[AttributeId] = [a.Attribute4].[Id]
        WHERE ([a.Attribute4].[Type] = N'Raw Sku') AND ([p0].[Id] = [a4].[ProductId])) AND EXISTS (
        SELECT 1
        FROM [Product_ProductAttribute] AS [a5]
        INNER JOIN [Product_Attribute] AS [a.Attribute5] ON [a5].[AttributeId] = [a.Attribute5].[Id]
        WHERE ([a.Attribute5].[Name] = N'SMALL') AND ([p0].[Id] = [a5].[ProductId]))) AND EXISTS (
        SELECT 1
        FROM [Product_ProductAttribute] AS [a6]
        INNER JOIN [Product_Attribute] AS [a.Attribute6] ON [a6].[AttributeId] = [a.Attribute6].[Id]
        WHERE ([a.Attribute6].[Type] = N'Raw Sku') AND ([p0].[Id] = [a6].[ProductId]))) AND EXISTS (
        SELECT 1
        FROM [Product_ProductAttribute] AS [a7]
        INNER JOIN [Product_Attribute] AS [a.Attribute7] ON [a7].[AttributeId] = [a.Attribute7].[Id]
        WHERE ([a.Attribute7].[Name] = N'LARGE') AND ([p0].[Id] = [a7].[ProductId]))) AND EXISTS (
        SELECT 1
        FROM [Product_ProductAttribute] AS [a8]
        INNER JOIN [Product_Attribute] AS [a.Attribute8] ON [a8].[AttributeId] = [a.Attribute8].[Id]
        WHERE ([a.Attribute8].[Name] = N'BLACK') AND ([p0].[Id] = [a8].[ProductId]))
) AS [t] ON [p.Attributes].[ProductId] = [t].[Id]
ORDER BY [t].[Id]
Microsoft.EntityFrameworkCore.Database.Command:Information: Executed DbCommand (156ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [p.Prices].[Division], [p.Prices].[ProductId], [p.Prices].[PriceId], [p.Prices].[EntryDate], [p.Prices].[EffectiveDate], [p.Prices].[ExpireDate]
FROM [Product_ProductPrice] AS [p.Prices]
INNER JOIN (
    SELECT [p1].[Id]
    FROM [Product] AS [p1]
    WHERE (((EXISTS (
        SELECT 1
        FROM [Product_ProductAttribute] AS [a9]
        INNER JOIN [Product_Attribute] AS [a.Attribute9] ON [a9].[AttributeId] = [a.Attribute9].[Id]
        WHERE ([a.Attribute9].[Type] = N'Raw Sku') AND ([p1].[Id] = [a9].[ProductId])) AND EXISTS (
        SELECT 1
        FROM [Product_ProductAttribute] AS [a10]
        INNER JOIN [Product_Attribute] AS [a.Attribute10] ON [a10].[AttributeId] = [a.Attribute10].[Id]
        WHERE ([a.Attribute10].[Name] = N'SMALL') AND ([p1].[Id] = [a10].[ProductId]))) AND EXISTS (
        SELECT 1
        FROM [Product_ProductAttribute] AS [a11]
        INNER JOIN [Product_Attribute] AS [a.Attribute11] ON [a11].[AttributeId] = [a.Attribute11].[Id]
        WHERE ([a.Attribute11].[Type] = N'Raw Sku') AND ([p1].[Id] = [a11].[ProductId]))) AND EXISTS (
        SELECT 1
        FROM [Product_ProductAttribute] AS [a12]
        INNER JOIN [Product_Attribute] AS [a.Attribute12] ON [a12].[AttributeId] = [a.Attribute12].[Id]
        WHERE ([a.Attribute12].[Name] = N'LARGE') AND ([p1].[Id] = [a12].[ProductId]))) AND EXISTS (
        SELECT 1
        FROM [Product_ProductAttribute] AS [a13]
        INNER JOIN [Product_Attribute] AS [a.Attribute13] ON [a13].[AttributeId] = [a.Attribute13].[Id]
        WHERE ([a.Attribute13].[Name] = N'BLACK') AND ([p1].[Id] = [a13].[ProductId]))
) AS [t0] ON [p.Prices].[ProductId] = [t0].[Id]
ORDER BY [t0].[Id]
public static partial class ExpressionUtils
{
    public static Expression<Func<TOuter, bool>> Any<TOuter, TInner>(Expression<Func<TOuter, IEnumerable<TInner>>> innerSelector, Expression<Func<TInner, bool>> innerPredicate)
    {
        var parameter = innerSelector.Parameters[0];
        var body = Expression.Call(
            typeof(Enumerable), nameof(Enumerable.Any), new[] { typeof(TInner) },
            innerSelector.Body, innerPredicate);
        return Expression.Lambda<Func<TOuter, bool>>(body, parameter);
    }
}
public static Expression<Func<TOuter, bool>> Any<TOuter, TInner>(Expression<Func<TOuter, IEnumerable<TInner>>> innerSelector, Rule r)
    => innerSelector.Any(ToWhere<TInner>(r));
foreach (var rule in filter.ToRuleGroup().Rules)
{
    entity = entity.Where(Rule.Any((Product p) => p.Attributes.Select(a => a.Attribute), rule));
}