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