【问题标题】:EF Core Automapper Recursive QueryEF Core Automapper 递归查询
【发布时间】:2021-01-15 09:14:06
【问题描述】:

我有一个自引用类

public class Project {
    public Guid Id { get; set; }
    public string Name { get; set; }
    public Guid? ParentId { get; set; }    
}

我已经设置了一个 psotgres 数据库,ef core 和 automapper 都可以正常工作。

我的 Dto 如下所示:

public class ProjectDto {
    public Guid Id { get; set; }
    public string Name { get; set; }
    public ICollection<ProjectPathEntry> Path { get; set; } = new HashSet<ProjectPathEntry>();
}

使用 helper-dto

public class ProjectPathEntry {
    public Guid Id { get; set; }
    public string Name { get; set; }
}

问题出现在 automapper 配置上 :) Id 和 Name 会按照约定自动映射,但 Path 显然无法直接映射。

我可以用单独的查询填充路径:

var projectPath = await dbContext.Projects.FromSqlInterpolated(
    $@"WITH recursive project(search_id, id, name) AS (
        SELECT p.""Id"", p.""Id"", p.""Name""
        FROM public.""Projects"" p

        UNION ALL

        SELECT p.""Id"", p2.id, p2.name
        FROM public.""Projects"" p, project p2
        WHERE p.""ParentProjectId"" = p2.search_id
    )
    SELECT proj.*
    FROM project
    JOIN public.""Projects"" proj on proj.""Id"" = project.id
    WHERE search_id = {project.Id}
        AND id != {project.Id}"
).ProjectTo<ProjectPathEntry>(mapper.ConfigurationProvider)
.ToListAsync(cancellationToken);

projectPath.Reverse();
project.Path = projectPath;

我能以某种方式将此查询嵌入到我的自动映射器配置中吗? 或者是否有可能将 SQL-View 添加到我的 pg-database 并通过 ef 实体配置映射它?

【问题讨论】:

  • 第一步是编写一个 EF linq 查询,Select,它可以满足您的需求。如果可行,可以将其翻译为ProjectTo

标签: c# .net-core tree entity-framework-core automapper


【解决方案1】:

我通过向我的数据库添加视图解决了我的问题:

CREATE VIEW "ProjectPathView"("ProjectId", "SortId", "Id", "Name") AS
    WITH RECURSIVE project(search_id, sort_id, id, name) AS (
        SELECT p."Id",
            1,
            p."Id",
            p."Name"
FROM "Projects" p
    UNION ALL
    SELECT p."Id",
        p2.sort_id + 1,
        p2.id,
        p2.name
    FROM "Projects" p,
        project p2
    WHERE p."ParentProjectId" = p2.search_id
)
SELECT project.search_id AS "ProjectId",
    project.sort_id AS "SortId",
    proj."Id",
    proj."Name"    
FROM project
JOIN "Projects" proj ON proj."Id" = project.id;

然后我创建了一个模型

public class ProjectPathEntry
{
    public Guid ProjectId { get; set; }
    public long SortId { get; set; }
    public Guid Id { get; set; }
    public string Name { get; set; }
}

代表我的观点。 在 EF 配置中,我设置了 ToView("ProjectPathView") 设置。 然后我将关系添加到我的基础模型中

public class Project {
    ...
        public virtual ICollection<ProjectPathEntry> Path { get; set; } = new HashSet<ProjectPathEntry>();
    ...
}

并设置HasMany 配置

builder.HasMany(p => p.Path)
       .WithOne()
       .HasForeignKey(p => p.ProjectId);

然后我的 ProjectDto 上的Path 属性可以通过 Automapper 自动映射。

【讨论】:

    猜你喜欢
    • 2021-07-29
    • 2021-12-05
    • 2020-11-27
    • 2020-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-18
    • 1970-01-01
    相关资源
    最近更新 更多