Slapper帮助Dapper实现一对多

Dapper的Query的方法提供了多个泛型重载可以帮助我们实现导航属性的查询

1对1

public class Employees4List
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Mobile { get; set; }
    public Department4Employees Department { get; set; }
}
public class Role4Employees
{
    public int Id { get; set; }
    public string Name { get; set; }
}
IEnumerable<Employees4List> GetEmployees()
{
    var sql = $@"
            select #e.[Id],#e.[Name],#e.[Mobile]
            ,#depart.id,#depart.name
            from dbo.T_Eemploye #e
            left join [dbo].[T_Department] #depart on #depart.id = #e.Department
            ";
    using (var conn = GetReadConnection())
    {
        var list = conn.Query<Employees4List, Department4Employees, Employees4List>(sql, (e, d) =>
        {
            e.Department = d;
            return e;
        });
        return list;
    }
}

1对n

但是如果职工类中加入这样一个属性呢 ? public List<Role4Employees> Role { get; set; }

public class Employees4List
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Mobile { get; set; }
    public List<Role4Employees> Role { get; set; }
    public Department4Employees Department { get; set; }
}
public class Role4Employees
{
    public int Id { get; set; }
    public string Name { get; set; }
}
public class Department4Employees
{
    public int Id { get; set; }
    public string Name { get; set; }
}

之前看到过这样一个方式,但是它是不能像我们想象的那样工作,这里如果一个Eemploye有多个角色,那就和原始的sql语句一样,他会产生重复的记录

IEnumerable<Employees4List> GetEmployees()
{
    var sql = $@"
    select #e.[Id],#e.[Name],#e.[Mobile]
    ,#depart.id,#depart.name
    ,#role.id,#role.name
    from dbo.T_Eemploye #e
    left join [dbo].[T_Department] #depart on #depart.id = #e.Department
    left join [dbo].[T_Role]       #role   on #role.value & #e.role = #role.value
    ";
    using (var conn = GetReadConnection())
    {
        var list = conn.Query<Employees4List, Department4Employees, Role4Employees, Employees4List>(sql,(e, d, r) =>
        {
            e.Department = d;
            e.Role.Add(r);
            return e;
        });
        return list;
    }
}

正确的方式是使用Slapper.Automapper,这个包需要独立安装

IEnumerable<Employees4List> GetEmployees()
{
    var sql = $@"
        select #e.[Id],#e.[Name],#e.[Mobile]
        ,#role.id Role_Id,#role.name Role_Name
        ,#depart.id Department_Id,#depart.name Department_Name
        from dbo.T_Eemploye #e
        left join [dbo].[T_Role]       #role   on #role.value & #e.role = #role.value
        left join [dbo].[T_Department] #depart on #depart.id = #e.Department
    ";
    using (var conn = GetReadConnection())
    {
        var dynamic = conn.Query<dynamic>(sql);

        Slapper.AutoMapper.Configuration.AddIdentifiers(typeof(Employees4List), new List<string> { "Id" });
        Slapper.AutoMapper.Configuration.AddIdentifiers(typeof(Role4Employees), new List<string> { "Id" });
        Slapper.AutoMapper.Configuration.AddIdentifier(typeof(Department4Employees), "Id");

        var list = (Slapper.AutoMapper.MapDynamic<Employees4List>(dynamic) as IEnumerable<Employees4List>).ToList();

        return list;
    }
}

通过AddIdentifier和AddIdentifier来识别外键是1对1还是1对n,需要注意的是这里需要对字段取别名,怎么取呢?

新的名称以在c#类中字段名称+下划线+导航类的字段名称

比如说Employees4List中有一个属性Role要做1对n查询,通过AddIdentifiers方法指明需要转换的类型名称和主键名称,其次在sql语句中通过

Role_Id和Role_Name来取别名,下划线前面的Role来自Employees4List的 Role属性,下划线后面的 Id 和 Name来自 Role4Employees

posted @ 2018-07-23 15:35  行走即歌  阅读(1935)  评论(0编辑  收藏  举报


感谢您的阅读,如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮。本文欢迎各位转载,但是转载文章之后必须在文章页面中给出作者和原文连接