У меня есть простая проблема: я хотел бы, чтобы одна из конечных точек RESTful обслуживала ресурс DTO (автоматически сопоставленный) со связанными с ним ресурсами только в качестве их идентификаторов. Однако, похоже, нет никакого способа реализовать это без загрузки целых (и тяжелых) связанных объектов. Рассмотрим следующую (сначала БД) примерную модель:
public partial class Blog
{
public int Id { get; set; }
public string Url { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
public partial class Post // some heavy entity
{
public int Id { get; set; }
public string Content { get; set; }
// other properties
}
и соответствующий DTO
// api/v1/blogs serves collection of following type
public class BlogSlimDto
{
public int Id { get; set; }
public string Url { get; set; }
public int[] PostIds { get; set; }
}
простым решением было бы извлечь все связанные Post
из базы данных и отбросить все данные, кроме идентификаторов, но это может быть неэффективным или даже невыполнимым в зависимости от размера связанного объекта Post
:
var result = ctx.Blogs.Include(blog => blog.Posts) //fecth everything and discard it on next line
.Select(blog => _mapper.Map<BlogSlimDto>(blog));
// simply use a profile that discards Posts but keeps their Ids, e.g.
// .forMember(dto => dto.PostIds, opt => opt.MapFrom(db.Posts.Select(p => p.Id)))
есть похожий вопрос, который предлагает решение используя анонимные типы, однако это совсем не работает с Automapper:
var result = ctx.Blogs.Select(blog => new {
blog.Id,
blog.Url,
PostIds = blog.Posts.Select(b => b.Id),
}).Select(ablog => _mapper.Map<BlogSlimDto>(ablog)); //throws, no mapping and such mapping cannot be defined
Приведенный выше код будет сгенерирован во время выполнения, поскольку сопоставление Automapper не определено. Хуже того, его нельзя определить, потому что существует нет поддержки анонимных типов в Automapper. Более того, решения с поочередным «ручным» назначением свойств, как правило, сложно поддерживать.
Существует ли альтернативное решение, которое позволяло бы запрашивать EF без извлечения всех связанных сущностей, позволяя при этом автоматически сопоставлять результат с BlogSlimDto
?