首頁 > 後端開發 > C++ > 用於從子屬性中選擇自訂 DTO 的 EF Core 程式碼能否高效重複使用?

用於從子屬性中選擇自訂 DTO 的 EF Core 程式碼能否高效重複使用?

Linda Hamilton
發布: 2025-01-23 19:48:14
原創
859 人瀏覽過

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

為子屬性選擇自訂 DTO 物件的程式碼可以在 EF Core 中重複使用嗎?

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,. Select() 運算可以使用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
        }
    };
登入後複製

查詢可以寫為:

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 Core 程式碼能否高效重複使用?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板