2010-04-10 53 views
2

如果我有,例如,多到許多稱爲用戶和角色表之間的「RolesToUsers」映射表,這裏是我如何做到這一點:更新許多到許多與LinqToSQL關係

// DataContext is db, usr is a User entity 
// newUserRolesMappings is a collection with the desired new mappings, probably 
// derived by looking at selections in a checkbox list of Roles on a User Edit page 
db.RolesToUsers.DeleteAllOnSubmit(usr.RolesToUsers); 
usr.RolesToUsers.Clear(); 
usr.RolesToUsers.AddRange(newUserRolesMappings); 

我曾經使用SQL分析器,並且這似乎會生成非常智能的SQL - 它只會刪除不再處於映射關係中的行,並且只添加關係中不存在的行。它不會像我以爲會那樣盲目地徹底清理和重建關係。

關於這個主題,互聯網出奇的安靜,查詢「LinqToSQL多對多」大多隻是提供了關於LinqToSQL數據映射器如何不「很好地支持」的文章。

其他人如何使用LinqToSQL更新多對多?

+2

從技術上講,這不是一個真正的ORM相當於多到很多,因爲你是手動清除連接表的。對ORM中m2m的「正確」支持可以將User對象建模爲具有名爲「Roles」的屬性(或集合),因此,ORM將負責編輯封面下的連接表。 – RobS 2010-04-10 12:12:51

+0

至少這是我的解釋無論如何.. HIH – RobS 2010-04-10 12:14:41

+1

@ RobS:同意。這也是我的解釋:如果你只關心一個特定的用戶,你看看'用戶'對象'角色'集合。如果您關心某個特定角色,則分別查看「角色」對象的「用戶」集合。那是一個ORM的想法,隱藏數據庫的東西,並像你一樣使用它只使用對象。 – 2010-04-10 12:25:49

回答

2

關係是一組事實。 Users,RolesUsersToRoles都是關係,把它看作更「一流」而不是另一個。你所做的事情是非常有意義的,這就是爲什麼它似乎很好地工作。

ORM世界屠殺關係模型甚至比SQL更差。特別是,它將制度化關係數據庫存儲對象集合的謬誤。他們沒有;他們存儲一系列事實。其中很多事實是實體,這就是爲什麼謬誤如此誘人。但大量的事實是關於許多其他類型的概念,例如成員資格,事件,狀態,意見,交易,變化,比較,歷史等等。

還認爲:

  1. 在某些時候,你可能想表明,當用戶採用了一定的作用,然後也許是否該角色處於待審批狀態,或暫時吊銷。我發現,我想在數據模型中表達的所有「關係」最終都要承載超過構成多對多關係的兩個外鍵的有效載荷。如果你的OR映射已經設置爲隱藏多對多(就像他們傾向於做的那樣),你會發現從代碼中斷到轉換到一個實體是相當痛苦的。
  2. 關係比二元關係更復雜。 「P教授在C班使用課本T.」可能是一種不可簡化的三元關係,不容易隱藏在教授對象的某些集合屬性後面。
    • 我剛剛注意到,恰好這個問題在幾分鐘前彈出爲SO question。從這個問題看來,JPA 2.0必須明確加入對三元關係的支持(是否處理四元關係?)。
+1

當然,它適用於他,但你不覺得你應該更喜歡獲取一個用戶對象並更新其角色集合,並讓ORM執行連接表邏輯?至少他使用了ORM,爲什麼他不應該從它的功能中受益呢? – 2010-04-10 12:43:12

+0

你對數據庫級別的關係是正確的,但是當涉及模式上方(或外部)的抽象/層時,我不同意 - UsersToRoles表在任何上下文之外都沒有用處,你有多大可能查詢只是表格本身? – RobS 2010-04-10 12:46:06

+0

@RobS,這很可能。首先,請注意我上面的兩點。其次,可以自行查詢UsersToRoles來構建聚合,例如每個角色的用戶數量,或者直方圖類型的查詢,例如有多少用戶擁有五個以上角色,甚至有多少用戶共享超過三個角色。最後一個問題在典型的ORM中很難回答。 – 2010-04-10 12:51:36

1

這可能不是你的問題的答案,但解釋爲什麼'互聯網在這個問題上令人驚訝的安靜':我想大多數人(包括我)只是更新/刪除/添加項目的一個n一對一的關係,因此從來不必自問你自己的問題。

就像當你有兩個表'用戶'和'角色',並且用例只是向/從用戶添加/刪除一個角色時。

只是在好奇:你需要在哪個應用程序中更新整個映射,就像你的例子?

+0

我有幾個我們使用的應用程序的例子,但我會使用這個例子: 我們有用戶,角色,RolesToUsers設置就像原始問題的例子。爲了編輯用戶所在的角色,管理控制檯的用戶編輯頁面上有一個複選框列表。每個複選框代表一個角色。因此,無論用戶在之前擔任什麼角色,當管理員按下「提交」編輯用戶時,我都會得到一個新的管理員希望用戶所在的角色列表(從複選框中)。 – 2010-04-12 12:11:10

+0

現在我很好奇。在LinqToSQL中看起來像什麼(假設這是你使用的)?你的意思是說你已經知道你正在刪除的n對n映射錶行的ID(何時是操作)?而且在做一個添加時,你總是隻是增加一行到n對n的關係? – 2010-04-12 12:29:08