#c# #sql #sql-server #entity-framework
#c# #sql #sql-сервер #entity-framework
Вопрос:
У меня есть запрос, который записан в формате, подобном этому:
bool filterQuotes = false;
bool filterInactive = false;
var res = await DbContext.CheckPlans
.Where(plan => plan.PlanID == currentPlanId)
.SelectMany(plan => plan.CheckActivityPlanDetail)
.Include(planDetail => planDetail.CheckActivity)
.ThenInclude(checkActivity => checkActivity.Setup)
.Where(planDetail => (!filterQuotes || planDetail.CheckActivity.ActivityType==0)
amp;amp; (!filterInactive || planDetail.IsActive))
.OrderBy(planDetail => planDetail.CheckActivity.Setup.Value)
.ToListAsync();
Как мне преобразовать этот запрос в обычный запрос SQL Server, чтобы увидеть, каков его результат?
Комментарии:
1. Вы хотите видеть SQL, который генерирует этот запрос, или вы хотите, чтобы SQL был эквивалентен этому запросу EF?
2. SQL-запрос, который он генерирует.
3. Вы используете EF или EF Core?
4. @trashr0x EF core. Я очень мало представляю, как пишутся эти методы, если бы кто-нибудь мог указать мне на документацию для ссылки, это было бы действительно потрясающе
5. Вы пытаетесь использовать SQL profiler для перехвата SQL-запроса после выполнения?
Ответ №1:
В Entity Framework есть несколько способов взглянуть на SQL, который генерирует запрос.
Примечание: все эти способы будут использовать этот запрос:
var query = DbContext.CheckPlans
.Where(plan => plan.PlanID == currentPlanId)
.SelectMany(plan => plan.CheckActivityPlanDetail)
.Include(planDetail => planDetail.CheckActivity)
.ThenInclude(checkActivity => checkActivity.Setup)
.Where(planDetail => (!filterQuotes || planDetail.CheckActivity.ActivityType==0)
amp;amp; (!filterInactive || planDetail.IsActive))
.OrderBy(planDetail => planDetail.CheckActivity.Setup.Value);
- Приведите
IQueryable
к anObjectQuery
и получите его строку трассировки:
// ObjectQuery is in the 'System.Data.Objects' namespace if EF version < 6
// starting with EF version 6 and upwards it's in the 'System.Data.Entity.Core.Objects' namespace
var sql = ((ObjectQuery) query).ToTraceString();
- Перехватите ведение журнала и распечатайте его в
Debug.WriteLine
:
// This code needs to be placed where you are creating your DbContext
context.Database.Log = s => Debug.WriteLine(s);
// ...
// Then when executing the query with
var results = query.ToListAsync();
// Your debug console in Visual Studio should contain all the information you need
- Конфигурация Entity Framework.
Если вы используете EF 6.1 и более поздние версии, вы можете использовать конфигурацию EF для создания перехватчика и записать его в текстовый файл, как описано здесь:
<interceptors>
<interceptor type="System.Data.Entity.Infrastructure.Interception.DatabaseLogger, EntityFramework">
<parameters>
<parameter value="C:TempLogOutput.txt"/>
<parameter value="true" type="System.Boolean"/>
</parameters>
</interceptor>
</interceptors>
- И, наконец, вы могли бы использовать LINQPad. Существует бесплатная версия, которая может подключаться к базе данных и где вы можете напрямую вводить выражения или операторы C #, и сгенерированный SQL отображается внизу, аналогично этому
Ответ №2:
DbContext.Database.Для свойства Log можно установить значение делегата для любого метода, который принимает строку. В этом примере операторы SQL записываются в консоль с помощью Console .Написать
using (var context = new BlogContext())
{
context.Database.Log = Console.Write;
var blog = context.Blogs.First(b => b.Title == "One Unicorn");
blog.Posts.First().Title = "Green Eggs and Ham";
blog.Posts.Add(new Post { Title = "I do not like them!" });
context.SaveChangesAsync().Wait();
}
Из: https://learn.microsoft.com/en-us/ef/ef6/fundamentals/logging-and-interception