【问题标题】:Entity Framework "Code supposed to be unreachable" on agrigated include expression聚合包含表达式的实体框架“代码应该无法访问”
【发布时间】:2019-05-31 10:21:12
【问题描述】:

第一

我创建了这个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 中运行包含表达式时,出现以下错误。

“代码应该无法访问”

这是我尝试过的两个示例,它们会引发此错误。

第一次尝试

这是来自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 专家来告诉我:-)

【问题讨论】:

    标签: c# entity-framework lambda entity-framework-core repository-pattern


    【解决方案1】:

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

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

    可以通过在 Locals/Watch 窗口中展开 entityIncludes 变量来查看 - 您将看到有关调试视图或 LambdaExpressionParameters 属性的异常。

    话虽如此,问题是由不正确的 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());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      相关资源
      最近更新 更多