Как исправить проблему n + 1 в Entity Framework Core 2.0? - PullRequest
0 голосов
/ 08 апреля 2020

У меня есть этот код

var query = DbContext.Set<WorkCertificate>()
                     .Include(u => u.WorkCertificateWorkers)
                     .Include(u => u.WorkCertificateGVSs)
                     .Where(filterExpression)
                     .Skip(filter.GetSkip()).Take(filter.GetTake());

var list = await query.ToListAsync();

Typebuilder из WorkCertificate. WorkCertificate наследуется от базового класса.

builder.HasMany(workCertificate => workCertificate.WorkCertificateWorkers)
    .WithOne(wcw => wcw.WorkCertificate)
    .HasForeignKey(wcw => wcw.WorkCertificateId);

builder.HasMany(workCertificate => workCertificate.WorkCertificateGVSs)
    .WithOne(wcw => wcw.WorkCertificate)
    .HasForeignKey(wcw => wcw.WorkCertificateId);

Этот код генерирует SQL. И вы можете видеть, что есть много подключений к БД, и это вызывает большие проблемы с производительностью.

2020-04-08 16:27:52.0918|INFO|SimpleConsoleLogger|Executed DbCommand (59ms) [Parameters=[@__filter_Data_Id_0='?', @__p_2='?', @__p_1='?'], CommandType='Text', CommandTimeout='30']
SELECT "u"."id", "u"."allowed_to_copy", "u"."approval_state", "u"."certificate_category", "u"."xmin", "u"."created_date", "u"."creator_id", "u"."deleted", "u"."global_id", "u"."gvs_analysis_required", "u"."location_detail", "u"."modified_date", "u"."original_number", "u"."previous_approval_state", "u"."status_key", "u"."work_type", "u"."discriminator", "u"."is_expired_message_sent", "u"."isolation_certificate_required", "u"."linked_isolation_certificate_type", "u"."linked_lockout_certificate_type", "u"."lockout_certificate_required", "u"."shift", "u"."work_description_detail"
FROM "public"."certificate" AS "u"
WHERE ("u"."discriminator" = 'workCertificate') AND (("u"."deleted" = FALSE) AND ("u"."id" = @__filter_Data_Id_0))
ORDER BY "u"."id"
LIMIT @__p_2 OFFSET @__p_1
2020-04-08 16:27:52.2706|INFO|SimpleConsoleLogger|Executed DbCommand (80ms) [Parameters=[@__filter_Data_Id_0='?', @__p_2='?', @__p_1='?'], CommandType='Text', CommandTimeout='30']

SELECT "u.WorkCertificateWorkers"."id", "u.WorkCertificateWorkers"."additional_info", "u.WorkCertificateWorkers"."certificate_state", "u.WorkCertificateWorkers"."created_date", "u.WorkCertificateWorkers"."name", "u.WorkCertificateWorkers"."occupation", "u.WorkCertificateWorkers"."position_id", "u.WorkCertificateWorkers"."position_title", "u.WorkCertificateWorkers"."profile_id", "u.WorkCertificateWorkers"."qualification", "u.WorkCertificateWorkers"."work_certificate_id"
FROM "public"."work_certificate_workers" AS "u.WorkCertificateWorkers"
INNER JOIN (
    SELECT "u0"."id"
    FROM "public"."certificate" AS "u0"
    WHERE ("u0"."discriminator" = 'workCertificate') AND (("u0"."deleted" = FALSE) AND ("u0"."id" = @__filter_Data_Id_0))
    ORDER BY "u0"."id"
    LIMIT @__p_2 OFFSET @__p_1
) AS "t" ON "u.WorkCertificateWorkers"."work_certificate_id" = "t"."id"
ORDER BY "t"."id"
2020-04-08 16:27:52.3493|INFO|SimpleConsoleLogger|Executed DbCommand (50ms) [Parameters=[@__filter_Data_Id_0='?', @__p_2='?', @__p_1='?'], CommandType='Text', CommandTimeout='30']

SELECT "u.WorkCertificateGVSs"."id", "u.WorkCertificateGVSs"."checked_date", "u.WorkCertificateGVSs"."checked_place", "u.WorkCertificateGVSs"."comment", "u.WorkCertificateGVSs"."max_allowed_concentration", "u.WorkCertificateGVSs"."measuring_tool_number", "u.WorkCertificateGVSs"."measuring_tool_verification_date", "u.WorkCertificateGVSs"."name", "u.WorkCertificateGVSs"."position_title", "u.WorkCertificateGVSs"."result", "u.WorkCertificateGVSs"."substance", "u.WorkCertificateGVSs"."type_key", "u.WorkCertificateGVSs"."unit_of_measure", "u.WorkCertificateGVSs"."work_certificate_id"
FROM "public"."work_certificate_gvs" AS "u.WorkCertificateGVSs"
INNER JOIN (
    SELECT "u1"."id"
    FROM "public"."certificate" AS "u1"
    WHERE ("u1"."discriminator" = 'workCertificate') AND (("u1"."deleted" = FALSE) AND ("u1"."id" = @__filter_Data_Id_0))
    ORDER BY "u1"."id"
    LIMIT @__p_2 OFFSET @__p_1
) AS "t0" ON "u.WorkCertificateGVSs"."work_certificate_id" = "t0"."id"
ORDER BY "t0"."id"

Как получить один запрос SQL вместо того, что я получаю сейчас?

1 Ответ

0 голосов
/ 09 апреля 2020

Я решил эту проблему путем обновления до ef core 3.1

...