/// <summary> /// . /// </summary> public class Entity { /// <summary> /// . /// </summary> public Guid Id { get; set; } } /// <summary> /// . /// </summary> public abstract class Meteor: Entity { /// <summary> /// . /// </summary> public string Name { get; set; } /// <summary> /// . /// </summary> public double Weight { get; set; } /// <summary> /// . /// </summary> public Material Material { get; set; } /// <summary> /// . /// </summary> public double DistanceToEarth { get; set; } /// <summary> /// . /// </summary> public RiskLevel RiskLevel { get; set; } } /// <summary> /// . /// </summary> public class SpaceMeteor: Meteor { /// <summary> /// / . /// </summary> public DateTime DetectedAt { get; set; } /// <summary> /// . /// </summary> public Person DetectingPerson { get; set; } /// <summary> /// , . /// </summary> public Galaxy PlaceOfOrigin { get; set; } } /// <summary> /// . /// </summary> public class ArtificialMeteor: Meteor { /// <summary> /// -. /// </summary> public Country Country { get; set; } /// <summary> /// -. /// </summary> public SecretFactory Maker { get; set; } /// <summary> /// . /// </summary> public string SerialNumber { get; set; } /// <summary> /// . /// </summary> public Person QualityEngineer { get; set; } }
/// <summary> /// DTO. /// </summary> public class BaseDto { public Guid Id { get; set; } } /// <summary> /// DTO . /// </summary> public abstract class MeteorDto: BaseDto { public string Name { get; set; } public double Weight { get; set; } public string MaterialName { get; set; } public Guid? MaterialId { get; set; } public double DistanceToEarth { get; set; } public string RiskLevelName { get; set; } public Guid RiskLevelId { get; set; } } /// <summary> /// DTO . /// </summary> public class SpaceMeteorDto: MeteorDto { public DateTime DetectedAt { get; set; } public string DetectingPersonName { get; set; } public Guid DetectingPersonId { get; set; } public string PlaceOfOriginName { get; set; } public Guid? PlaceOfOriginId { get; set; } } /// <summary> /// DTO . /// </summary> public class ArtificialMeteorDto: MeteorDto { public string CountryName { get; set; } public Guid CountryId { get; set; } public string MakerName { get; set; } public string MakerAddress { get; set; } public string MakerDirectorName { get; set; } public Guid MakerId { get; set; } public string SerialNumber { get; set; } public string QualityEngineerName { get; set; } public Guid QualityEngineerId { get; set; } }
interface IDtoMapper<TEntity, TDto> { IEnumerable<TDto> Map(IEnumerable<TEntity> entities); }
interface IDtoFetcher<TEntity, TDto> { IEnumerable<TDto> Fetch(IQueryable<TEntity> query, Paging paging, FetchAim fetchAim); }
/// <summary> /// DTO. /// </summary> public enum FetchAim { /// <summary> /// /// </summary> None, /// <summary> /// /// </summary> Card, /// <summary> /// /// </summary> List, /// <summary> /// /// </summary> Index }
SELECT (id, name) FROM meteors
IQueryable<Meteor> meteorQuery = _meteorRepository.Query(); IEnumerable<MeteorDto> meteors = meteorQuery .Select(m => new MeteorDto { Id = m.Id, Name = m.Name }) .ToList();
class SpaceMeteorDtoFetcher: IDtoFetcher<SpaceMeteor, SpaceMeteorDto> { public IEnumerable<SpaceMeteorDto> Fetch(IQueryable<SpaceMeteor> query, Page page, FetchAim fetchAim) { if (fetchAim == FetchAim.Index) { return query .Select(m => new SpaceMeteorDto { Id = m.Id, Name = m.Name }) .Page(page) .ToList(); } else if (fetchAim == FetchAim.List) { // ... } // ... } }
/// <summary> /// DTO . /// </summary> public class SpaceMeteorDtoFetcher: BaseMeteorDtoFetcher<SpaceMeteor, SpaceMeteorDto> { static SpaceMeteorDtoFetcher() { CreateMapForIndex(); CreateMapForList(); CreateMapForCard(); } private static void CreateMapForIndex() { var map = CreateFetchMap(FetchAim.Index); // MapBaseForIndex(map); } private static void CreateMapForList() { var map = CreateFetchMap(FetchAim.List); // MapBaseForList(map); MapSpecificForList(map); } /// <summary> /// . /// </summary> /// <param name="map"> </param> private static void MapSpecificForList(IFetchMap<SpaceMeteor, SpaceMeteorDto> map) { map.Map(d => d.DetectedAt, e => e.DetectedAt) .Map(d => d.DetectingPersonName, e => e.DetectingPerson.FullName) .Map(d => d.PlaceOfOriginName, e => e.PlaceOfOrigin.Name); } private static void CreateMapForCard() { var map = CreateFetchMap(FetchAim.Card); MapBaseForCard(map); MapSpecificForCard(map); } /// <summary> /// . /// </summary> /// <param name="map"> </param> private static void MapSpecificForCard(IFetchMap<SpaceMeteor, SpaceMeteorDto> map) { map.Map(d => d.DetectedAt, e => e.DetectedAt) .Map(d => d.DetectingPersonId, e => e.DetectingPerson.Id) .Map(d => d.PlaceOfOriginId, e => e.PlaceOfOrigin.Id); } public SpaceMeteorDtoFetcher(IRepository repository) : base(repository) { } }
public interface IFetchMap<TSource, TTarget> where TSource : Entity where TTarget : BaseDto { /// <summary> /// DTO. /// </summary> IFetchMap<TSource, TTarget> Map<TProperty>( Expression<Func<TTarget, TProperty>> targetProperty, Expression<Func<TSource, TProperty>> sourceProperty); /// <summary> /// DTO, . /// </summary> IFetchMap<TSource, TTarget> CustomMap(Action<IQueryable<TSource>, IEnumerable<TTarget>> fetchOperation); }
Source: https://habr.com/ru/post/172787/
All Articles