简体   繁体   English

如何修复 Entity Framework Core 2.0 中的 n+1 问题?

[英]How to fix n+1 problem in Entity Framework Core 2.0?

I have this code我有这个代码

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 of WorkCertificate . TypebuilderWorkCertificate WorkCertificate is inherited from base class. WorkCertificate继承自基础 class。

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);

This code generates SQL.此代码生成 SQL。 And you can see there are a lot of connections to DB and it causes large performance issues.你可以看到有很多与 DB 的连接,这会导致很大的性能问题。

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"

How can I get single SQL query instead of what I am getting now?如何获得单个 SQL 查询而不是我现在得到的查询?

I solved this problem by upgrading to ef core 3.1我通过升级到 ef core 3.1 解决了这个问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM