使用 Ef Core 执行多个 ProjectS 层时出错
Error when doing mulitple ProjectTo layers with EfCore
我正在尝试创建一个 "design guide" 用于在我的公司中构建 rest apis,我希望有一个带有 automapper、asp.net 核心和 ef 核心的 3 层结构.
Database Layer : DbSet Entities
Business Layer : Application Models
Api/Rest/External Layer : Dto Object
我已经通过以下要点成功地做到了这一点:https://gist.github.com/Angelinsky7/49c86333584e3f9cece44a88e7febd4e
但是正如你所看到的,我需要使用 hack 来完成这项工作...(https://gist.github.com/Angelinsky7/49c86333584e3f9cece44a88e7febd4e#file-automapper_bug_lambda_projection-cs-L23-L24), (https://gist.github.com/Angelinsky7/49c86333584e3f9cece44a88e7febd4e#file-automapper_bug_lambda_projection-cs-L89) and (https://gist.github.com/Angelinsky7/49c86333584e3f9cece44a88e7febd4e#file-automapper_bug_lambda_projection-cs-L93)
public IEnumerable<SubLayer2> _Subs { get; set; } = new HashSet<SubLayer2>();
public ICollection<SubLayer2> Subs => (ICollection<SubLayer2>)_Subs;
cfg.CreateMap<Layer1, Layer2>()
.ForMember(p => p._Subs, opt => opt.MapFrom(src => src.Subs));
cfg.CreateMap<Layer2, Layer3>()
.ForMember(p => p.Subs, opt => opt.MapFrom(src => src._Subs));
而且我非常不喜欢它(因为即使它像那样工作,在更复杂的 senarii 中,它也不再工作了)
如果我不破解:https://gist.github.com/Angelinsky7/0e26507c07c066376d5a4de8726dd1f2
在第 3 层作为 IEnumerable 的 InMemory EfCore 案例中:(在创建问题之前我没有这个)
Unhandled exception. System.InvalidOperationException: The LINQ expression 'dtoSubLayer2' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync()
在第 3 层作为 IEnumerable 的 SqlServer EfCore 案例中:(我想使用的)
InvalidOperationException: When called from 'VisitLambda', rewriting a node of type 'System.Linq.Expressions.ParameterExpression' must return a non-null value of the same type. Alternatively, override 'VisitLambda' and change it to not visit children of this type.
在所有以 Layer3 作为 ICollection 的 EfCore 中:
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
我做错了什么?这完全不可能吗?有没有办法让我找到弹出异常并自定义此行为的 NullReferenceException 或 VisitLambda?拥有这种解决方案将是完美的,因为我将拥有我想要的东西 api...
Source/destination 类型
internal class Layer1 {
public Int64 Id { get; set; }
public ICollection<SubLayer1> Subs { get; set; } = new HashSet<SubLayer1>();
}
internal class SubLayer1 {
public Int64 Id { get; set; }
public Int64 LayerId { get; set; }
}
internal class Layer2 {
public Int64 Id { get; set; }
public ICollection<SubLayer2> Subs { get; set; } = new HashSet<SubLayer2>();
}
internal class SubLayer2 {
public Int64 Id { get; set; }
}
internal class Layer3 {
public Int64 Id { get; set; }
public IEnumerable<SubLayer3> Subs { get; set; } = new HashSet<SubLayer3>();
}
internal class SubLayer3 {
public Int64 Id { get; set; }
}
映射配置
cfg.CreateMap<Layer1, Layer2>();
cfg.CreateMap<SubLayer1, SubLayer2>();
cfg.CreateMap<Layer2, Layer3>();
cfg.CreateMap<SubLayer2, SubLayer3>();
版本:x.y.z
<PackageReference Include="AutoMapper" Version="9.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.0" />
预期行为
我应该能够多次使用 ProjectTo 更改图层,而无需使用技巧。我应该可以在 ICollection 和 IEnumerable 之间进行选择
实际行为
根据实施情况,出现 3 个异常(大多数情况下是 'VisitLambda' lambda 一个
重现步骤
https://gist.github.com/Angelinsky7/0e26507c07c066376d5a4de8726dd1f2
感谢所有帮助,感谢您抽出宝贵时间!!!
(很抱歉,如果这是一个 efcore 问题,但我在想:"because i can create a "hack" in automapper it may be here")
我来这里是因为 automapper 团队认为这不是他们的错误 (https://github.com/AutoMapper/AutoMapper/issues/3280)
automapper 似乎不能做我想做的事。
我的错。
感谢社区帮助我。
我正在尝试创建一个 "design guide" 用于在我的公司中构建 rest apis,我希望有一个带有 automapper、asp.net 核心和 ef 核心的 3 层结构.
Database Layer : DbSet Entities
Business Layer : Application Models
Api/Rest/External Layer : Dto Object
我已经通过以下要点成功地做到了这一点:https://gist.github.com/Angelinsky7/49c86333584e3f9cece44a88e7febd4e
但是正如你所看到的,我需要使用 hack 来完成这项工作...(https://gist.github.com/Angelinsky7/49c86333584e3f9cece44a88e7febd4e#file-automapper_bug_lambda_projection-cs-L23-L24), (https://gist.github.com/Angelinsky7/49c86333584e3f9cece44a88e7febd4e#file-automapper_bug_lambda_projection-cs-L89) and (https://gist.github.com/Angelinsky7/49c86333584e3f9cece44a88e7febd4e#file-automapper_bug_lambda_projection-cs-L93)
public IEnumerable<SubLayer2> _Subs { get; set; } = new HashSet<SubLayer2>();
public ICollection<SubLayer2> Subs => (ICollection<SubLayer2>)_Subs;
cfg.CreateMap<Layer1, Layer2>()
.ForMember(p => p._Subs, opt => opt.MapFrom(src => src.Subs));
cfg.CreateMap<Layer2, Layer3>()
.ForMember(p => p.Subs, opt => opt.MapFrom(src => src._Subs));
而且我非常不喜欢它(因为即使它像那样工作,在更复杂的 senarii 中,它也不再工作了)
如果我不破解:https://gist.github.com/Angelinsky7/0e26507c07c066376d5a4de8726dd1f2
在第 3 层作为 IEnumerable 的 InMemory EfCore 案例中:(在创建问题之前我没有这个)
Unhandled exception. System.InvalidOperationException: The LINQ expression 'dtoSubLayer2' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync()
在第 3 层作为 IEnumerable 的 SqlServer EfCore 案例中:(我想使用的)
InvalidOperationException: When called from 'VisitLambda', rewriting a node of type 'System.Linq.Expressions.ParameterExpression' must return a non-null value of the same type. Alternatively, override 'VisitLambda' and change it to not visit children of this type.
在所有以 Layer3 作为 ICollection 的 EfCore 中:
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
我做错了什么?这完全不可能吗?有没有办法让我找到弹出异常并自定义此行为的 NullReferenceException 或 VisitLambda?拥有这种解决方案将是完美的,因为我将拥有我想要的东西 api...
Source/destination 类型
internal class Layer1 {
public Int64 Id { get; set; }
public ICollection<SubLayer1> Subs { get; set; } = new HashSet<SubLayer1>();
}
internal class SubLayer1 {
public Int64 Id { get; set; }
public Int64 LayerId { get; set; }
}
internal class Layer2 {
public Int64 Id { get; set; }
public ICollection<SubLayer2> Subs { get; set; } = new HashSet<SubLayer2>();
}
internal class SubLayer2 {
public Int64 Id { get; set; }
}
internal class Layer3 {
public Int64 Id { get; set; }
public IEnumerable<SubLayer3> Subs { get; set; } = new HashSet<SubLayer3>();
}
internal class SubLayer3 {
public Int64 Id { get; set; }
}
映射配置
cfg.CreateMap<Layer1, Layer2>();
cfg.CreateMap<SubLayer1, SubLayer2>();
cfg.CreateMap<Layer2, Layer3>();
cfg.CreateMap<SubLayer2, SubLayer3>();
版本:x.y.z
<PackageReference Include="AutoMapper" Version="9.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.0" />
预期行为
我应该能够多次使用 ProjectTo 更改图层,而无需使用技巧。我应该可以在 ICollection 和 IEnumerable 之间进行选择
实际行为
根据实施情况,出现 3 个异常(大多数情况下是 'VisitLambda' lambda 一个
重现步骤
https://gist.github.com/Angelinsky7/0e26507c07c066376d5a4de8726dd1f2
感谢所有帮助,感谢您抽出宝贵时间!!! (很抱歉,如果这是一个 efcore 问题,但我在想:"because i can create a "hack" in automapper it may be here")
我来这里是因为 automapper 团队认为这不是他们的错误 (https://github.com/AutoMapper/AutoMapper/issues/3280)
automapper 似乎不能做我想做的事。 我的错。 感谢社区帮助我。