EF Core 查询转换为单个或多个查询

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

有没有办法检测查询如何从 EF Core 转换为 SQL Server?我需要检测我的 EF Core 查询是否使用

AsSplitQuery
选项并且 actually 转换为多个 SQL 查询。例如,如果我的 EF Core 表达式查询是使用
AsSplitQuery
编写的,但不包含任何可枚举的导航属性(在
Include
Select
表达式中),它将被转换为单个 SQL 查询。另一方面,如果 EF Core 表达式查询包含可枚举导航属性(在
Include
Select
表达式中)并使用
AsSplitQuery
选项,它将被转换为多个 SQL 查询。

c# .net entity-framework
2个回答
0
投票

LINQ 查询上有 .ToQueryString() 方法,您可以在其中查看 EF Core 生成的底层查询


0
投票

如果您点击此链接:

https://learn.microsoft.com/en-us/ef/core/logging-events-diagnostics/diagnostic-listeners

并按照描述编写“DiagnosticObserver”代码。

您可以寻找这个“事件名称”。

https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.diagnostics.coreeventid.queryexecutionplanned?view=efcore-8.0

当我在具有多个 .Include 项的 EF 查询上本地捕获此值时..并且我明确使用了“.AsSplitQuery()”..下面的魔术字符串

queryContext => 新的 SplitQueryingEnumerable

出现。

虽然是“魔绳”狩猎..我想它可以解决你的需求。

这是一些代码..这是上面“learn.microsoft”链接的修改版本。

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore.Diagnostics;

namespace MyApp.DomainDataLayer.EntityFramework.Contexts.Listeners;

public class KeyValueObserver : IObserver<KeyValuePair<string, object>>
{
    private static ICollection<KeyValuePair<string, object>> _events = new List<KeyValuePair<string, object>>();

    public void OnCompleted()
        => throw new NotImplementedException();

    public void OnError(Exception error)
        => throw new NotImplementedException();

    public void OnNext(KeyValuePair<string, object> value)
    {
        if (!_events.Select(kvp => kvp.Key).Contains(value.Key))
        {
            _events.Add(value);
        }

        // if (value.Key == CoreEventId.ContextInitialized.Name)
        // {
        //     ContextInitializedEventData payload = (ContextInitializedEventData) value.Value;
        //     Console.WriteLine($"EF is initializing {payload.Context.GetType().Name} ");
        // }
        //
        // if (value.Key == RelationalEventId.ConnectionOpening.Name)
        // {
        //     ConnectionEventData payload = (ConnectionEventData) value.Value;
        //     Console.WriteLine($"EF is opening a connection to {payload.Connection.ConnectionString} ");
        // }
        
        if (value.Key == CoreEventId.QueryExecutionPlanned.Name)
        {
            QueryExpressionEventData payload = (QueryExpressionEventData) value.Value;
            Console.WriteLine($"EF is initializing {payload.Expression.GetType().Name} ");
            string fullExpressionAsstring = payload.Expression.ToString();
            if (fullExpressionAsstring.Contains("SplitQueryingEnumerable"))
            {
                Console.WriteLine($"DING DING DING : {fullExpressionAsstring} ");
            }
        }

        string myKeys = string.Join(",", _events.Select(kvp => kvp.Key));
        string temp = string.Empty;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.