EF Core Automapper 递归查询
EF Core Automapper Recursive Query
我有一个自引用class
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; }
}
问题现在出现在自动映射器配置上:) Id 和 Name 会按照约定自动映射,但路径显然不能直接映射。
我可以用单独的查询填充路径:
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 数据库并通过 ef 实体配置映射它?
我通过向我的数据库添加一个视图解决了我的问题:
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自动映射了
我有一个自引用class
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; }
}
问题现在出现在自动映射器配置上:) Id 和 Name 会按照约定自动映射,但路径显然不能直接映射。
我可以用单独的查询填充路径:
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 数据库并通过 ef 实体配置映射它?
我通过向我的数据库添加一个视图解决了我的问题:
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自动映射了