代码之家  ›  专栏  ›  技术社区  ›  Andrii Shvydkyi

使用OData和AutoMapper展开子导航属性时“序列不包含匹配元素”

  •  2
  • Andrii Shvydkyi  · 技术社区  · 7 年前

    尝试使用以下查询展开导航属性时出现异常“Sequence contains no matching element”: http://localhost:5000/odata/users ?$expand=角色。没有$expand关键字的请求有效。从接收DTO对象 AutoMapper


    实体框架实体:

    public class User {
      public string Id { get; set; }
      public string Username { get; set; }
      public string Email { get; set; }
      public virtual ICollection<UserRole> UserRoles { get; set; }
    }
    
    public class Role {
      public string Id { get; set; }
      public string Name { get; set; }
    }
    
    public class UserRole {
      public string UserId { get; set; }
      public string RoleId { get; set; }
    }
    

    DTO型号:

    public class UserModel {
      public string Id { get; set; }
      public string Username { get; set; }
      public string Email { get; set; }
      public IEnumerable<RoleModel> Roles { get; set; }
    }
    
    public class RoleModel
    {
        public string Id { get; set; }
        public string Name { get; set; }
    }
    

    配置:

    CreateMap<UserRole, RoleModel>()
         .ForMember(x => x.Id, x => x.MapFrom(m => m.UserId))
         .ForMember(x => x.Name, x => x.MapFrom(m => m.Role.Name));
    
    CreateMap<User, UserModel>()
         .ForMember(dest => dest.Roles, opts => opts.MapFrom(src => src.UserRoles))
         .ReverseMap()
         .ForMember(dest => dest.UserRoles, o => o.Ignore());
    

    控制器动作方法:

    [HttpGet]
    [EnableQuery]
    public IQueryable<UserModel> Get() =>
        _userManager.Users.ProjectTo<UserModel>(_mapper.ConfigurationProvider);
    

    Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.CorrelatedCollectionOptimizingVisitor 当它试图在由生成的表达式中查找where子句时

    var originalCorrelationPredicate = collectionQueryModel.BodyClauses
        .OfType<WhereClause>()
        .Single(c => c.Predicate is NullSafeEqualExpression);
    

    如果我更改 汽车制造商 对于以下情况,不会引发异常,但会对每个用户记录分别执行角色子查询:

    CreateMap<User, UserModel>()
        .ForMember(dest => dest.Roles, opts => 
              opts.MapFrom(src => 
                  src.UserRoles.Select(ur => new RoleModel {
                        Id = ur.UserId,
                        Name = ur.Role.Name
                    })))
        .ReverseMap()
        .ForMember(dest => dest.UserRoles, o => o.Ignore());
    

    我做错了什么?


    补充:

    手写变体(按其应有的方式工作):

    .......
    Roles = .Call System.Linq.Enumerable.Select(
         $x.UserRoles,
         .Lambda 
    #Lambda2<System.Func`2[Test.Data.UserRole,Test.Models.RoleModel]>),
    .......
    

    由AutoMapper生成:

    .......
    Roles = .Call System.Linq.Enumerable.ToList(.Call 
         System.Linq.Enumerable.Select(
               $x.UserRoles,
               .Lambda 
    #Lambda2<System.Func`2[Test.Data.UserRole,Test.Models.RoleModel]>)),
    .......
    

    汽车制造商 ToList() ?

    0 回复  |  直到 7 年前
    推荐文章