我已设法加载子类型的数据
ImageCell
和
TextCell
属于
Cell
.
public abstract class Cell : IAggregateRoot
{
public int CellId { get; set; }
public string CellType { get; set; }
public int RowIndex { get; set; }
public int ColIndex { get; set; }
public int RowSpan { get; set; }
public int ColSpan { get; set; }
public int PageId { get; set; }
public Page Page { get; set; }
}
public class TextCell : Cell
{
public String Text { get; set; }
}
public class ImageCell : Cell
{
public String Url { get; set; }
}
我添加了的鉴别器值
CellType
基于枚举。
public enum CellEnum
{
Cell,
TextCell,
ImageCell
}
在
DbContext.OnModelCreating()
我是这样配置的:
builder.Entity<Cell>()
.HasDiscriminator(c => c.CellType)
.IsComplete(false);
从那时起,我想我通过创建一个服务
CellType
.
Program.cs
builder.Services.AddScoped<IService<Cell>, GenericService<Cell>>();
builder.Services.AddScoped<IService<ImageCell>, GenericService<ImageCell>>();
builder.Services.AddScoped<IService<TextCell>, GenericService<TextCell>>();
IService.cs
namespace Core.Interfaces
{
public interface IService<T> where T : class, IAggregateRoot
{
Task<T> GetByIdAsync(int id);
Task<IEnumerable<T>> ListAsync();
// Adapt to use specifications
Task<IEnumerable<T>> ListAsyncWithSpec(Specification<T> spec);
Task DeleteByIdAsync(int id);
Task AddAsync(T t);
Task UpdateAsyc(T t);
}
}
GenericService
只是使用的存储库的实现
IService<T>
.
然后我创建了一个
DTO
.
namespace API.DTOs
{
public class CellDTO : DTO
{
public int CellId { get; set; }
public string CellType { get; set; }
public int RowIndex { get; set; }
public int ColIndex { get; set; }
public int RowSpan { get; set; }
public int ColSpan { get; set; }
public int PageId { get; set; }
// CellType specific properties
public string Url { get; set; }
public string Text { get; set; }
}
}
并创建了
MappingProfile
.
CreateMap<Cell, CellDTO>()
.ForMember(dto => dto.Text, options => options.MapFrom(src => src.CellType.Equals(CellEnum.TextCell.ToString()) ? ((TextCell)src).Text : null))
.ForMember(dto => dto.Url, options => options.MapFrom(src => src.CellType.Equals(CellEnum.ImageCell.ToString()) ? ((ImageCell)src).Url : null));
控制器现在看起来真的很乱:
namespace API.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class CellsController : BaseController<Cell, CellDTO>
{
private readonly IService<ImageCell> _imageCellService;
private readonly IService<TextCell> _textCellService;
public CellsController(IService<Cell> service, IService<ImageCell> imageCellService, IService<TextCell> textCellService, IMapper mapper) : base(service, mapper)
{
_imageCellService = imageCellService;
_textCellService = textCellService;
}
[HttpGet]
public override async Task<ICollection<CellDTO>> Get()
{
var result = new List<CellDTO>();
// Add ImageCells
ICollection<ImageCell> imageCells = (ICollection<ImageCell>)await _imageCellService.ListAsync();
result.AddRange(_mapper.Map<ICollection<ImageCell>, ICollection<CellDTO>>(imageCells));
// Add TextCells
ICollection<TextCell> textCells = (ICollection<TextCell>)await _textCellService.ListAsync();
result.AddRange(_mapper.Map<ICollection<TextCell>, ICollection<CellDTO>>(textCells));
return result;
}
}
}
我如何在不复制这么多代码和使用多个的情况下加载所有子类
I服务<T>
对于每种专用类型?
编辑#1
我正在使用
Ardalis.Specification
,但找不到任何有用的东西。
using Ardalis.Specification;
using Core.Entities.Cells;
namespace Core.Specifications
{
public class CellSpecification : Specification<Cell>
{
public CellSpecification()
{
}
}
}
编辑#2
示例输出
[
{
"cellId": 1,
"cellType": "ImageCell",
"rowIndex": 0,
"colIndex": 0,
"rowSpan": 1,
"colSpan": 1,
"pageId": 1,
"url": "http://bild0.png",
"text": null
},
{
"cellId": 2,
"cellType": "ImageCell",
"rowIndex": 0,
"colIndex": 0,
"rowSpan": 1,
"colSpan": 1,
"pageId": 2,
"url": "http://bild1.png",
"text": null
},
{
"cellId": 3,
"cellType": "ImageCell",
"rowIndex": 0,
"colIndex": 0,
"rowSpan": 1,
"colSpan": 1,
"pageId": 3,
"url": "http://bild2.png",
"text": null
},
{
"cellId": 4,
"cellType": "ImageCell",
"rowIndex": 0,
"colIndex": 0,
"rowSpan": 1,
"colSpan": 1,
"pageId": 4,
"url": "http://bild3.png",
"text": null
},
{
"cellId": 5,
"cellType": "ImageCell",
"rowIndex": 0,
"colIndex": 0,
"rowSpan": 1,
"colSpan": 1,
"pageId": 5,
"url": "http://bild4.png",
"text": null
},
{
"cellId": 6,
"cellType": "TextCell",
"rowIndex": 0,
"colIndex": 1,
"rowSpan": 1,
"colSpan": 2,
"pageId": 1,
"url": null,
"text": "Es ist..."
},
{
"cellId": 7,
"cellType": "TextCell",
"rowIndex": 0,
"colIndex": 1,
"rowSpan": 1,
"colSpan": 2,
"pageId": 2,
"url": null,
"text": "Borja hockt..."
},
{
"cellId": 8,
"cellType": "TextCell",
"rowIndex": 0,
"colIndex": 1,
"rowSpan": 1,
"colSpan": 2,
"pageId": 3,
"url": null,
"text": "..."
},
{
"cellId": 9,
"cellType": "TextCell",
"rowIndex": 0,
"colIndex": 1,
"rowSpan": 1,
"colSpan": 2,
"pageId": 4,
"url": null,
"text": "«Das Versteck ..."
},
{
"cellId": 10,
"cellType": "TextCell",
"rowIndex": 0,
"colIndex": 1,
"rowSpan": 1,
"colSpan": 2,
"pageId": 5,
"url": null,
"text": "Die Ameise...:"
}
]