Entity Framework Core에서는 식을 사용하여 쿼리하여 DTO 개체로 변환할 수 있습니다. 이 기능은 제공된 모델:
public class Model { public int ModelId { get; set; } public string ModelName { get; set; } public virtual ICollection<ChildModel> ChildModels { get; set; } // Other properties, collections, etc. public static Expression<Func<Model, ModelDto>> AsDto => model => new ModelDto { ModelId = model.ModelId, ModelName = model.ModelName, ChildModels = model.ChildModels.AsQueryable().Select(ChildModel.AsDto).ToList() }; }
및 쿼리:
dbContext.Models.Where(m => SomeCriteria).Select(Model.AsDto).ToList();
에서 예시된 것처럼 개체 및 모든 하위 컬렉션에 대해 잘 작동합니다. 그러나 질문이 발생합니다. 어떻게 유사할 수 있습니까? 컬렉션이 아닌 하위 엔터티에 대해 동작을 달성할 수 있습니까? 예를 들어, Model 클래스에 다음 속성이 포함되어 있는 경우:
public AnotherChildModel AnotherChildModel { get; set; }
표현식에 변환을 추가할 수 있습니다:
public static Expression<Func<Model, ModelDto>> AsDto => model => new ModelDto { ModelId = model.ModelId, ModelName = model.ModelName, ChildModels = model.ChildModels.AsQueryable().Select(ChildModel.AsDto).ToList(), AnotherChildModel = new AnotherChildModelDto { AnotherChildModelId = model.AnotherChildModelId } };
그러나 두 번째 하위 모델이 필요할 때마다 이 코드를 반복합니다. DTO 개체로 변환하는 것은 바람직하지 않습니다. 단일 엔터티에 .Select()를 사용하는 것의 대안이 있습니까?
여러 라이브러리가 이 문제에 대한 직관적인 솔루션을 제공합니다.
1. LINQKit:
LINQKit을 사용하면 ExpandableAttribute를 사용하여 .Select() 작업을 개별 엔터티에 적용할 수 있습니다.
[Expandable(nameof(AsDtoImpl))] public static ModelDto AsDto(Model model) { _asDtoImpl ??= AsDtoImpl() .Compile(); return _asDtoImpl(model); } private static Func<Model, ModelDto> _asDtoImpl; private static Expression<Func<Model, ModelDto>> AsDtoImpl => model => new ModelDto { ModelId = model.ModelId, ModelName = model.ModelName, ChildModels = model.ChildModels.AsQueryable().Select(ChildModel.AsDto).ToList(), AnotherChildModel = new AnotherChildModelDto { AnotherChildModelId = model.AnotherChildModelId } };
그런 다음 쿼리를 다음과 같이 작성할 수 있습니다.
dbContext.Models .Where(m => SomeCriteria).Select(m => Model.AsDto(m)) .AsExpandable() .ToList();
2. NeinLinq:
LINQKit과 유사하게 NeinLinq는 InjectLambda 속성을 활용합니다.
[InjectLambda] public static ModelDto AsDto(Model model) { _asDto ??= AsDto() .Compile(); return _asDto(model); } private static Func<Model, ModelDto> _asDto; private static Expression<Func<Model, ModelDto>> AsDto => model => new ModelDto { ModelId = model.ModelId, ModelName = model.ModelName, ChildModels = model.ChildModels.AsQueryable().Select(ChildModel.AsDto).ToList(), AnotherChildModel = new AnotherChildModelDto { AnotherChildModelId = model.AnotherChildModelId } };
쿼리는 다음과 같이 수정할 수 있습니다.
dbContext.Models .Where(m => SomeCriteria).Select(m => Model.AsDto(m)) .ToInjectable() .ToList();
3. DelegateDecompiler:
DelegateDecompiler는 Computed 속성을 사용하여 간결한 접근 방식을 제공합니다.
[Computed] public static ModelDto AsDto(Model model) => new ModelDto { ModelId = model.ModelId, ModelName = model.ModelName, ChildModels = model.ChildModels.AsQueryable().Select(ChildModel.AsDto).ToList(), AnotherChildModel = new AnotherChildModelDto { AnotherChildModelId = model.AnotherChildModelId } }
쿼리는 다음과 같이 단순화될 수 있습니다.
dbContext.Models .Where(m => SomeCriteria).Select(m => Model.AsDto(m)) .Decompile() .ToList();
각 라이브러리는 목표를 달성합니다. EF Core 처리 전에 식 트리를 수정하여 반복되는 코드가 필요하지 않습니다. 또한 세 가지 모두 해당 IQueryProvider를 삽입하려면 호출이 필요합니다.
위 내용은 하위 속성에서 사용자 지정 DTO를 선택하기 위한 EF 핵심 코드를 효율적으로 재사용할 수 있나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!