Heim >Backend-Entwicklung >C++ >Kann EF-Core-Code zur Auswahl benutzerdefinierter DTOs aus untergeordneten Eigenschaften effizient wiederverwendet werden?
Entity Framework Core ermöglicht Abfragen mithilfe von Ausdrücken zur Konvertierung in DTO-Objekte. Diese Funktionalität funktioniert gut für das Objekt und alle untergeordneten Sammlungen, wie am Beispiel des bereitgestellten Modells:
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() }; }
Und der Abfrage:
dbContext.Models.Where(m => SomeCriteria).Select(Model.AsDto).ToList();
Es stellt sich jedoch die Frage: Wie kann ähnliches erfolgen? Kann ein Verhalten für eine untergeordnete Entität erreicht werden, die keine Sammlung ist? Wenn die Model-Klasse beispielsweise die Eigenschaft enthält:
public AnotherChildModel AnotherChildModel { get; set; }
Eine Konvertierung kann dem Ausdruck hinzugefügt werden:
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 } };
Dieser Code wird jedoch jedes Mal wiederholt, wenn das zweite untergeordnete Modell dies erfordert in ein DTO-Objekt konvertiert werden soll, ist unerwünscht. Gibt es eine Alternative zur Verwendung von .Select() für eine einzelne Entität?
Mehrere Bibliotheken bieten eine intuitive Lösung für dieses Problem:
1. LINQKit:
Mit LINQKit kann die .Select()-Operation mithilfe des ExpandableAttribute: auf einzelne Entitäten angewendet werden:
[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 } };
Die Abfrage kann dann wie folgt geschrieben werden:
dbContext.Models .Where(m => SomeCriteria).Select(m => Model.AsDto(m)) .AsExpandable() .ToList();
2. NeinLinq:
Ähnlich wie LINQKit verwendet NeinLinq das InjectLambda-Attribut:
[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 } };
Die Abfrage kann wie folgt geändert werden:
dbContext.Models .Where(m => SomeCriteria).Select(m => Model.AsDto(m)) .ToInjectable() .ToList();
3. DelegateDecompiler:
DelegateDecompiler bietet einen prägnanten Ansatz unter Verwendung des Computed-Attributs:
[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 } }
Die Abfrage kann wie folgt vereinfacht werden:
dbContext.Models .Where(m => SomeCriteria).Select(m => Model.AsDto(m)) .Decompile() .ToList();
Jede dieser Bibliotheken erreicht das Ziel durch Ändern des Ausdrucksbaums vor der EF Core-Verarbeitung, wodurch die Notwendigkeit für wiederholten Code vermieden wird. Darüber hinaus benötigen alle drei einen Aufruf, um ihren jeweiligen IQueryProvider einzufügen.
Das obige ist der detaillierte Inhalt vonKann EF-Core-Code zur Auswahl benutzerdefinierter DTOs aus untergeordneten Eigenschaften effizient wiederverwendet werden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!