Entity Framework "Code supposed to be unreachable" on agrigated include 表达式

Entity Framework "Code supposed to be unreachable" on agrigated include expression

第一

我已经创建了这个 GitHub repo 只需按 F5 键就会遇到这个错误 所以你应该很容易尝试这个。此问题中的所有链接都指向该存储库。

代码流

我的控制器中的 following expression code 是我想让前端开发人员包含他们需要的关系的地方。

// The included tables I want to control from my controller
Expression<Func<CompanyDto, object>>[] includes = { x => x.Employees, x => x.Cars };

var companyDto2 = await service.GetByIdAsync(1, includes).ConfigureAwait(false);

然后在我的服务层I map the dto includes to my entity includes并将它们发送到存储库

var entityIncludes = mapper.Map<Expression<Func<Entity, object>>[]>(includes);

var result = await repository.GetByIdAsync(id, entityIncludes).ConfigureAwait(false);

错误

当我 运行 在我的 repository 中包含表达式时,出现以下错误。

"Code supposed to be unreachable"

这里有 两个例子 我试过的抛出这个错误的东西。

第一次尝试

这是 enter link description here

的尝试
var queryableResultWithIncludes = includes
.Aggregate(dbContext.Set<TEntity>().AsQueryable(),
(current, include) => current.Include(include));

// return the result of the query using the specification's criteria expression
var result = queryableResultWithIncludes.AsEnumerable();

// Here we get "Code supposed to be unreachable"
var neverHappens = result .ToList();

第二次尝试

// Second attempts
if (includes.Length > 0)
{
    IQueryable<TEntity> set = includes
       .Aggregate<Expression<Func<TEntity, object>>, IQueryable<TEntity>>
       (dbContext.Set<TEntity>(), (current, expression) => current.Include(expression));

    // Here we also get "Code supposed to be unreachable"
    return await set.SingleOrDefaultAsync(s => s.Id == id).ConfigureAwait(false);
}

总结

我错过了什么?我在做某种反模式的事情吗?我需要一些 EF 专家告诉我:-)

正如我所怀疑的那样,这个问题与 EF 没有任何共同之处,而是 AutoMapper 表达式翻译产生的无效表达式:

var entityIncludes = mapper.Map<Expression<Func<Entity, object>>[]>(includes);

可以通过扩展 Locals/Watch window 中的 entityIncludes 变量来查看 - 您将在调试视图或 Parameters [=33= 中看到有问题的异常] LambdaExpression.

话虽如此,问题是由不正确的 AutoMapper 配置引起的,特别是缺少 AddExpressionMapping()。您为 AutoMapper 全局配置执行了此操作,但您的代码正在使用依赖注入,因此您需要在那里执行此操作,例如

当前

services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
// Auto Mapper Configurations
AutoMapper.Mapper.Initialize(cfg =>
{
    cfg.DisableConstructorMapping();
    cfg.AddExpressionMapping();
    cfg.AddProfile<CompanyProfile>();
});

应该是

services.AddAutoMapper(cfg =>
{
    cfg.DisableConstructorMapping();
    cfg.AddExpressionMapping();    
}, AppDomain.CurrentDomain.GetAssemblies());