有没有办法检测查询如何从 EF Core 转换为 SQL Server?我需要检测我的 EF Core 查询是否使用
AsSplitQuery
选项并且 actually 转换为多个 SQL 查询。例如,如果我的 EF Core 表达式查询是使用 AsSplitQuery
编写的,但不包含任何可枚举的导航属性(在 Include
和 Select
表达式中),它将被转换为单个 SQL 查询。另一方面,如果 EF Core 表达式查询包含可枚举导航属性(在 Include
或 Select
表达式中)并使用 AsSplitQuery
选项,它将被转换为多个 SQL 查询。
LINQ 查询上有 .ToQueryString() 方法,您可以在其中查看 EF Core 生成的底层查询
如果您点击此链接:
https://learn.microsoft.com/en-us/ef/core/logging-events-diagnostics/diagnostic-listeners
并按照描述编写“DiagnosticObserver”代码。
您可以寻找这个“事件名称”。
当我在具有多个 .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;
}
}