首页 > 其他分享 >EFCore join table and AutoMapper

EFCore join table and AutoMapper

时间:2022-08-28 14:22:53浏览次数:94  
标签:__ join roles Roles get AutoMapper table Id

EFCore join table and AutoMapper

Question

I want to query all users from my ASP.net Identity Users table and map them to a simple DTO like this:

public class UserDto
{
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public string Email { get; set; }
    public IEnumerable<string> Roles { get; set; }
}

The list of roles should only contain the names of the roles, so I join the roles in from the roles table and get the names. Now I want to simplify this by using AutoMapper and map the results directly into my DTO.

var users = await _userManager.Users
            .AsNoTracking()
            .Include(u => u.Roles)
            .Select(u => new {
                User = u,
                Roles = u.Roles
                    .Join(_roleManager.Roles, 
                            a => a.RoleId, 
                            b => b.Id, 
                            (a, b) => b.Name)
                    .ToList()
            })
            .ToListAsync();

I'm struggling to find a good solution to map this data to a list of UserDto objects with AutoMapper. I tried to user ProjectTo<UserDto> and implement the table join in my mapper configuration but I get a lot of efcore warnings that my queries are executed on the client.

Question: Is there a simple and efficient way to do this with AutoMapper and efcore?

Update Even without AutoMapper it produces a warning :(

var users = await _userManager.Users
            .AsNoTracking()
            .Include(u => u.Roles)
            .Select(u => new UserDto {
                Firstname = u.Firstname,
                Lastname = u.Lastname,
                Email = u.Email,
                Roles = u.Roles
                    .Join(_roleManager.Roles, 
                            a => a.RoleId, 
                            b => b.Id, 
                            (a, b) => b.Name)
                    .ToList()
            })                
            .ToListAsync();

This is the efcore logging output:

info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1]
      Executed DbCommand (2ms) [Parameters=[@__get_Item_0='?' (Size = 450)], CommandType='Text', CommandTimeout='30']
      SELECT TOP(1) [e].[Id], [e].[AccessFailedCount], [e].[Address], [e].[City], [e].[ConcurrencyStamp], [e].[Country], [e].[CustomerIdentifier], [e].[Email], [e].[EmailConfirmed], [e].[Firstname], [e].[Gender], [e].[Lastname], [e].[LockoutEnabled], [e].[LockoutEnd], [e].[NormalizedEmail], [e].[NormalizedUserName], [e].[PasswordHash], [e].[PhoneNumber], [e].[PhoneNumberConfirmed], [e].[Region], [e].[SecurityStamp], [e].[TwoFactorEnabled], [e].[UserName], [e].[ZipCode]
      FROM [AspNetUsers] AS [e]
      WHERE [e].[Id] = @__get_Item_0

info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1]
      Executed DbCommand (2ms) [Parameters=[@__normalizedRoleName_0='?' (Size = 256)], CommandType='Text', CommandTimeout='30']
      SELECT TOP(2) [r].[Id], [r].[ConcurrencyStamp], [r].[Name], [r].[NormalizedName]
      FROM [AspNetRoles] AS [r]
      WHERE [r].[NormalizedName] = @__normalizedRoleName_0

info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1]
      Executed DbCommand (6ms) [Parameters=[@__get_Item_0='?' (Size = 450), @__get_Item_1='?' (Size = 450)], CommandType='Text', CommandTimeout='30']
      SELECT TOP(1) [e].[UserId], [e].[RoleId]
      FROM [AspNetUserRoles] AS [e]
      WHERE ([e].[UserId] = @__get_Item_0) AND ([e].[RoleId] = @__get_Item_1)

warn: Microsoft.EntityFrameworkCore.Query.Internal.SqlServerQueryCompilationContextFactory[6]
      The Include operation for navigation: 'u.Roles' was ignored because the target navigation is not reachable in the final query results. To configure this warning use the DbContextOptionsBuilder.ConfigureWarnings API (event id 'CoreEventId.IncludeIgnoredWarning'). ConfigureWarnings can be used when overriding the DbContext.OnConfiguring method or using AddDbContext on the application service provider.

info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1]
      Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT [u].[Firstname], [u].[Lastname], [u].[Email], [u].[Id]
      FROM [AspNetUsers] AS [u]

info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1]
      Executed DbCommand (2ms) [Parameters=[@_outer_Id='?' (Size = 450)], CommandType='Text', CommandTimeout='30']
      SELECT [b].[Name]
      FROM [AspNetUserRoles] AS [a]
      INNER JOIN [AspNetRoles] AS [b] ON [a].[RoleId] = [b].[Id]
      WHERE @_outer_Id = [a].[UserId]

info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1]
      Executed DbCommand (1ms) [Parameters=[@_outer_Id='?' (Size = 450)], CommandType='Text', CommandTimeout='30']
      SELECT [b].[Name]
      FROM [AspNetUserRoles] AS [a]
      INNER JOIN [AspNetRoles] AS [b] ON [a].[RoleId] = [b].[Id]
      WHERE @_outer_Id = [a].[UserId]

Update 2

Following the warning, I just removed the Include statement an found a working solution:

var users = await _userManager.Users
            .AsNoTracking()
            .Select(u => new UserDto {
                Firstname = u.Firstname,
                Lastname = u.Lastname,
                Email = u.Email,
                Roles = u.Roles
                    .Join(_roleManager.Roles, 
                            a => a.RoleId, 
                            b => b.Id, 
                            (a, b) => b.Name)
                    .ToList()
            })                
            .ToListAsync();

 

 

Accepted Answer

I removed the Include statement from the query, moved the select statement to my AutoMapper profile and added the roles table as a parameter to my ProjectTo statement. Now its working as expected and not producing any efcore warnings.

ef query

        var users = await _userManager.Users
            .AsNoTracking()
            .ProjectTo<UserDto>(new { roles = _roleManager.Roles })              
            .ToListAsync();

automapper profile

        IQueryable<IdentityRole> roles = null;
        CreateMap<User, UserDto>()
            .ForMember(x => x.Roles, opt => 
                opt.MapFrom(src => 
                    src.Roles
                        .Join(roles, a => a.RoleId, b => b.Id, (a, b) => b.Name)
                        .ToList()
                )
            );

 

标签:__,join,roles,Roles,get,AutoMapper,table,Id
From: https://www.cnblogs.com/chucklu/p/16632694.html

相关文章

  • 关于qtableview开发过程中的一些记录
    使用QTableWidget刷新数据后,经常会自动展示为table首行。为了显示刷新数据前所在的位置,解决办法如下:     先记住滚动条位置,刷新数据后,再重置滚动条位置。伪代码如......
  • matlab中数据结构之-tables
    作为matlab中的一种数据结构,是一种按行和列存储信息的一种表格式的数据结构,同一列中的数据具有相同的长度,和我们平常见到的表差不多。使用关键table函数创建,格式为tabl......
  • innodb数据库 OPTIMIZE TABLE 提示Table does not support optimize, doing recreate
    Tabledoesnotsupportoptimize,doingrecreate+analyzeinstead提要:1.MySQL官方建议不要经常(每小时或每天)进行碎片整理,一般根据实际情况,只需要每周或者每月整理一......
  • ERROR 1118 (42000): Row size too large. The maximum row size for the used table
    项目一直用的oracle数据库运行都正常,后来由于某种原因需要更换成MySQL,更改好配置后直接运行项目有hibernate自动建表结果看到控台日志中有个错误:ERROR1118(42000):Ro......
  • element-ui 在 el-table 标题中添加小图标
    效果如下:html代码:<divclass="table-boxcus-table-box"><el-table:data="ruleForm.tableData"borderstyle="width:100%"><el-table-columnprop="o......
  • (转)CentOS6 iptables 记录指定IP的网络访问日志
     修改文件/etc/rsyslog.conf加入#DIYiptablesLogsave#kern.warning/var/log/iptables/iptables.logkern.debug/var/log/iptables/iptables.log修改文件/etc/......
  • Mysql 系列 | join 优化
    上一篇中说了join语句的执行过程,了解了深层逻辑,则优化方案呼之欲出。Multi-RangeRead(MRR)优化select*fromt1wherea>=1anda<=100;回表时,根据ID去主键索引......
  • 通过iptables转发到TDSQL实现外网访问云数据库
    腾讯云有些TDSQL,如pgsql版的不能通过外网访问。此时提供2种方案,一种是nginx转发,一种是iptables。这看起来都需要额外的服务器成本,没办法。这里我们使用iptables,因为最方便......
  • LINQ:Group Join
    一、数据准备publicclassEmployee{publicintID{get;set;}publicstringName{get;set;}publicintAddressId{get;set;......
  • iptables学习笔记
    原文链接:朱双印的iptables博客目录第一章基本概念第二章常用命令第三章iptables匹配条件第四章iptables扩展匹配条件第五章iptables的黑白名单机制第六章iptables自......