gpt4 book ai didi

c# - 我可以重用代码来为 EF Core 的子属性选择自定义 DTO 对象吗?

转载 作者:行者123 更新时间:2023-12-02 16:16:59 26 4
gpt4 key购买 nike

使用 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();

我的问题是关于尝试找到一种方法来为不是集合的 child 做类似的事情。如果我已经添加到我的模型中:

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() 的方法?

最佳答案

有几个库允许以直观的方式做到这一点:

LINQKit

[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();

更新:对于 EF Core,LINQKit 可以全局配置,AsExpanding() 可以省略。

builder
.UseSqlServer(connectionString)
.WithExpressionExpanding(); // enabling LINQKit extension

NeinLinq - 几乎与 LINQKit 中的相同

[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();

更新:对于 EF Core,NenLinq 可以全局配置,ToInjectable() 可以省略。

builder
.UseSqlServer(connectionString)
.WithLambdaInjection(); // enabling NeinLinq extension

DelegateDecompiler - 比其他人更简洁

[Compute]
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 处理之前纠正表达式树。它们都需要额外的调用来注入(inject)它自己的 IQueryProvider

关于c# - 我可以重用代码来为 EF Core 的子属性选择自定义 DTO 对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66378438/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com