I have a self-referencing class
public class Project {
public Guid Id { get; set; }
public string Name { get; set; }
public Guid? ParentId { get; set; }
}
I have setup a psotgres database with ef core and automapper all working.
My Dto looks as follows:
public class ProjectDto {
public Guid Id { get; set; }
public string Name { get; set; }
public ICollection<ProjectPathEntry> Path { get; set; } = new HashSet<ProjectPathEntry>();
}
with the helper-dto
public class ProjectPathEntry {
public Guid Id { get; set; }
public string Name { get; set; }
}
The problem comes now with the automapper config:) The Id and Name automaticly get mapped by convention but the Path obviously cannot get mapped directly.
I can fill the Path with a separate query:
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;
can I somehow embedd this query in my automapper config? Or is there a possibility to add a SQL-View to my pg-database and map it via ef entity configuration?
I solved my problem by adding a View to my Database:
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;
Then I created a model
public class ProjectPathEntry
{
public Guid ProjectId { get; set; }
public long SortId { get; set; }
public Guid Id { get; set; }
public string Name { get; set; }
}
which represents my View. In the EF configuration I set the ToView("ProjectPathView")
setting. I then added the relationship to my base Model
public class Project {
...
public virtual ICollection<ProjectPathEntry> Path { get; set; } = new HashSet<ProjectPathEntry>();
...
}
and set the HasMany
Configuration
builder.HasMany(p => p.Path)
.WithOne()
.HasForeignKey(p => p.ProjectId);
Then the Path
Property on my ProjectDto can be mapped automaticly via Automapper.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.