在 Hot Chocolate 框架中使用 DTO(使用 EFCore)
我们在热巧克力框架内使用EF核心来访问一些SQL数据库。 为了克服计算字段的问题(描述在这里)我们使用DTOS。
在下面的示例中,这很好。在查询“ foo”时,称为“ getfoo”方法,它使用计算参数创建了一个“ foodto”对象。
[UseProjection]
[UseFiltering]
[UseSorting]
public IQueryable<fooDTO> GetFoo([Service] ApiDbContext context) {
return context.fooSet.AsEnumerable().Select(f => CreateFooDTO(f)).AsQueryable();
}
private static fooDTO CreateFooDTO(foo f){
return new fooDTO{
param1 = f.param1,
param2 = f.param2,
computedParam3 = param2 - param1,
};
}
但是,当我们想在查询“ bar”引用“ foo”时使用dtos时,事情出了问题:
{
bar {
foo
}
}
对于那种情况,我们提供了以下方法:
[UseProjection]
[UseFiltering]
[UseSorting]
public IQueryable<barDTO> GetBar([Service] ApiDbContext context){
return context.barSet.AsEnumerable().Select(b => CreateBarDTO(b)).AsQueryable();
}
private static barDTO CreateBarDTO(bar b){
return new barDTO{
param1 = b.param1,
param2 = b.param2,
param3 = CreateFooDTO(b.foo)
};
}
这里的“ b.foo”似乎总是无效的,这意味着从未实现食物。
我的问题:
- 这个问题与热巧克力或EF核心有关吗?
- 在这种情况下,如何正确使用DTO?
We are using EF Core within the Hot Chocolate framework to access some SQL databases.
To overcome the issue with computed fields (described here) we make use of DTOs.
This works perfectly fine in the example below. When querying for "Foo", the "GetFoo" method is called which created a "fooDTO" object with the computed parameter.
[UseProjection]
[UseFiltering]
[UseSorting]
public IQueryable<fooDTO> GetFoo([Service] ApiDbContext context) {
return context.fooSet.AsEnumerable().Select(f => CreateFooDTO(f)).AsQueryable();
}
private static fooDTO CreateFooDTO(foo f){
return new fooDTO{
param1 = f.param1,
param2 = f.param2,
computedParam3 = param2 - param1,
};
}
However, things go wrong when we want use DTOs when querying for "Bar" referring "Foo":
{
bar {
foo
}
}
For that case we provided the following methods:
[UseProjection]
[UseFiltering]
[UseSorting]
public IQueryable<barDTO> GetBar([Service] ApiDbContext context){
return context.barSet.AsEnumerable().Select(b => CreateBarDTO(b)).AsQueryable();
}
private static barDTO CreateBarDTO(bar b){
return new barDTO{
param1 = b.param1,
param2 = b.param2,
param3 = CreateFooDTO(b.foo)
};
}
Here "b.foo" seems to be always null, meaning that fooDTO is never materialized.
My questions:
- Is this problem related to Hot Chocolate or EF Core?
- How to properly use DTOs in this case?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您在这里有几种选择,使用AutoMapper,它是
projectto
或在这种情况下有助于使用库。我建议使用 linqkit 。它需要仅配置
dbContextoptions
:由于EF Core只能与ExpressionTree一起使用,因此您必须以某种方式将此树传递到Linq查询。
linqkit
具有标记方法及其表达模拟的能力。然后,在扩展过程中,它将在查询翻译过程中注入所需的零件。假设您已经配置了dbContext以使用
linqkit
,则可以通过ExpandBableAbeatTribute
:用法很简单:
它将与AutoMapper的<:代码> projectto 但不配置映射。稍后,您可能会发现简化许多类似的谓词或其他重复的LINQ查询部分是有用的。
You have several choices here, using Automapper and it's
ProjectTo
or using libraries which helps in such case.I would suggest to use LINQKit. It needs just configuring
DbContextOptions
:Since EF Core can work only with ExpressionTree, you have to pass this tree to LINQ query somehow.
LINQKit
has ability to mark methods and their Expression analogue together. Then during expanding it will inject needed parts during query translation.Assuming that you have configured your DbContext to use
LINQKit
, you can extend your methods with ExpressionTree versions viaExpandableAttribute
:Then usage is simple:
It will generate the same projection as Automapper's
ProjectTo
but without configuring mapping. Later you may find how it useful to simplify a lot of similar predicates or other repetitive LINQ query parts.