2016-08-24 48 views
0

我正在使用Dapper構建自定義ORM。我有以下表格:這是一個在自定義orm中實現這種關聯場景的優雅方式嗎?

  • 用戶
  • 角色
  • 權限
  • RolePermission

我的存儲過程有2種選擇:1基礎用戶信息,1用戶的角色信息。基本的用戶信息被反序列化爲一個用戶對象。 RolePermission信息被反序列化爲一個自定義的RolePermission對象,然後以編程方式關聯到User對象。你在自定義的ORM中做對象圖實現有多複雜?例如,EF採用一種很好且簡單的面向對象方法來獲取這樣的角色名稱:User.UserRoles.Role.Name。然而,這是通過使用複雜而複雜的f/w實現的,該f/w根據db fk關聯自動映射實體連接。它還帶有性能開銷。我的想法是創造我的實體類如下:

  • MyCompany.Entities.Entity.User.User
  • MyCompany.Entities.Entity.User.RolePermission

因此,我RolePermission對象將完全適合用戶實體,無需外部依賴。這將使RolePermission對象在User對象的上下文中保持儘可能輕量級。它不需要任何額外的屬性來支持其他實體/域/用法。這看起來像一個優雅(簡單,有效,高效)的解決方案。對於在自定義ORM中創建複雜對象的這種方法,您有什麼想法?

回答

0

我一直都在做這類事情,而且非常簡單。你會在兩個查詢中做到這一點。這兩個查詢可以在同一個sproc中並返回不同的結果集,也可以是對數據庫的兩個獨立調用。我通常做後者,即使我們使用允許多個結果集返回的mssql。

所以首先:您正在查詢用戶(淺)和可選的用戶詳細信息(包括角色信息)(深層)。

public IEnumerable<User> GetUsers(int? userID, bool withDetails) 
     { 
      var users = db.Query<User>(@" select * 
              from dbo.Users u 
              where (@userID IS NULL OR u.Id = @userID)", new { userID }); 

      if (withDetails) 
      { 
       var rolePermissions = db.Query<RolePermission>(@" select * 
                    from dbo.RolePermissions rp 
                    where rp.UserId IN (select val from dbo.udf_ConvertIntListToTable(@userId_list))", new { userId_list = String.Join(',', users.Select(s => s.UserId)) }); 
       foreach(var user in users) 
       { 
        user.RolePermissions = rolePermissions.Where(w => w.UserId == user.UserId); 
       } 
      } 
     } 

的幾個注意事項:

  • dbo.udf_ConvertIntListToTable是很好的建立和執行重大。搜索網頁,你會發現它。如果找不到,我會將其作爲要點加載。
  • RolePermission需要引用外部用戶(我使用UserId)。此外,該查詢可能會映射您提到的其他數據(例如,角色,權限等)。
  • 我有大量的擴展來清理上述內容。我儘可能保持原始狀態,以便了解發生了什麼。
  • 對於列表等,您現在有一個非常輕的查詢(withDetails = false),以及一個較重的查詢,並將所有數據很好地包裝到其聚合根(User)中。
相關問題