Heim > Backend-Entwicklung > C++ > Kann EF-Core-Code zur Auswahl benutzerdefinierter DTOs aus untergeordneten Eigenschaften effizient wiederverwendet werden?

Kann EF-Core-Code zur Auswahl benutzerdefinierter DTOs aus untergeordneten Eigenschaften effizient wiederverwendet werden?

Linda Hamilton
Freigeben: 2025-01-23 19:48:14
Original
937 Leute haben es durchsucht

Can EF Core Code for Selecting Custom DTOs from Child Properties Be Reused Efficiently?

Kann Code zum Auswählen eines benutzerdefinierten DTO-Objekts für eine untergeordnete Eigenschaft mit EF Core 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()
        };
}
Nach dem Login kopieren

Und der Abfrage:

dbContext.Models.Where(m => SomeCriteria).Select(Model.AsDto).ToList();
Nach dem Login kopieren

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; }
Nach dem Login kopieren

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
        }
    };
Nach dem Login kopieren

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?

Lösungen

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
        }
    };
Nach dem Login kopieren

Die Abfrage kann dann wie folgt geschrieben werden:

dbContext.Models
   .Where(m => SomeCriteria).Select(m => Model.AsDto(m))
   .AsExpandable()
   .ToList();
Nach dem Login kopieren

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
        }
    };
Nach dem Login kopieren

Die Abfrage kann wie folgt geändert werden:

dbContext.Models
   .Where(m => SomeCriteria).Select(m => Model.AsDto(m))
   .ToInjectable()
   .ToList();
Nach dem Login kopieren

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
        }
    }
Nach dem Login kopieren

Die Abfrage kann wie folgt vereinfacht werden:

dbContext.Models
   .Where(m => SomeCriteria).Select(m => Model.AsDto(m))
   .Decompile()
   .ToList();
Nach dem Login kopieren

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!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage