Maison > développement back-end > C++ > Le code EF Core pour la sélection de DTO personnalisés à partir des propriétés enfants peut-il être réutilisé efficacement ?

Le code EF Core pour la sélection de DTO personnalisés à partir des propriétés enfants peut-il être réutilisé efficacement ?

Linda Hamilton
Libérer: 2025-01-23 19:48:14
original
859 Les gens l'ont consulté

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

Le code permettant de sélectionner un objet DTO personnalisé pour une propriété enfant peut-il être réutilisé avec EF Core ?

Entity Framework Core permet d'effectuer des requêtes à l'aide d'expressions à convertir en objets DTO. Cette fonctionnalité fonctionne bien pour l'objet et toutes les collections enfants, comme en témoigne le modèle fourni :

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()
        };
}
Copier après la connexion

Et la requête :

dbContext.Models.Where(m => SomeCriteria).Select(Model.AsDto).ToList();
Copier après la connexion

Cependant, la question se pose : comment des similaires peuvent-ils le comportement peut-il être atteint pour une entité enfant qui n'est pas une collection ? Par exemple, si la classe Model inclut la propriété :

public AnotherChildModel AnotherChildModel { get; set; }
Copier après la connexion

Une conversion peut être ajoutée à l'expression :

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
        }
    };
Copier après la connexion

Mais répéter ce code à chaque fois que le deuxième modèle enfant doit être converti en objet DTO n'est pas souhaitable. Existe-t-il une alternative à l'utilisation de .Select() pour une seule entité ?

Solutions

Plusieurs bibliothèques offrent une solution intuitive à ce problème :

1. LINQKit :
Avec LINQKit, l'opération .Select() peut être appliquée à des entités individuelles à l'aide de ExpandableAttribute :

[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
        }
    };
Copier après la connexion

La requête peut ensuite être écrite comme :

dbContext.Models
   .Where(m => SomeCriteria).Select(m => Model.AsDto(m))
   .AsExpandable()
   .ToList();
Copier après la connexion

2. NeinLinq :
Semblable à LINQKit, NeinLinq utilise l'attribut 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
        }
    };
Copier après la connexion

La requête peut être modifiée comme suit :

dbContext.Models
   .Where(m => SomeCriteria).Select(m => Model.AsDto(m))
   .ToInjectable()
   .ToList();
Copier après la connexion

3. DelegateDecompiler :
DelegateDecompiler propose une approche concise en utilisant l'attribut 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
        }
    }
Copier après la connexion

La requête peut être simplifiée en :

dbContext.Models
   .Where(m => SomeCriteria).Select(m => Model.AsDto(m))
   .Decompile()
   .ToList();
Copier après la connexion

Chacune de ces bibliothèques atteint l'objectif en modifiant l'arborescence d'expression avant le traitement EF Core, évitant ainsi le besoin de code répété. De plus, tous les trois nécessitent un appel pour injecter leur IQueryProvider respectif.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal