2015-07-20 60 views
1

我有一個多選表單需要保存到數據庫中。用戶可以在隨後的訪問中編輯他們的選擇。這些項目在具有唯一ID的表中定義,因此表單僅傳回一個ID列表。在實體框架中比較和插入/更新/刪除子項

它是這樣的:

Fruits: 
    { id=1, name="apple" } 
    { id=2, name="orange" } 
    { id=3, name="banana" } 

People: 
    { id=1, name="user", fruits=apple,orange } 

在DB有一個鏈接表連接的人民和水果的ID標識。

現在,當我收到編輯請求時,我需要與現有水果進行比較,以瞭解是否需要添加或刪除條目。

foreach (var fruit in existing_fruits) 
{ 
    if (post_fruits.Where(e => e.id == fruit.id).Count() == 0) user.Fruits.Remove(fruit); 
} 

foreach (var fruit in post_fruits) 
{ 
    if (existing_fruits.Where(e => e.id == fruit.id).Count() == 0) 
    { 
     var entity = context.Fruit.Where(e => e.id == fruit.id); 
     user.Fruits.Add(entity); 
    } 
} 

正如你可以看到有多個循環和多個該列表上的來電,這使我不知道是否有在做這一個更清潔的方式?

+0

這是一個樣板,但是一個高度可重用的輔助功能的常設候選人。我還會刪除重複兩次的查詢,一次要計數,一次要搜索。 –

回答

1

如果你使用的。任何方法在這裏(儘管它仍然使用了兩個循環,但它是更有效):

foreach (var fruit in existing_fruits) 
    if (!post_fruits.Any(e => e.id == fruit.id)) user.Fruits.Remove(fruit); 

foreach (var fruit in post_fruits) 
{ 
    if (existing_fruits.Any(e => e.id == fruit.id)) continue; 
    var entity = context.FirstOrDefault(e => e.id == fruit.id); 
    if(entity != null) user.Fruits.Add(entity); 
} 

但最好是DB架構更改爲:

Fruits: 
    { id=1, name="apple" } 
    { id=2, name="orange" } 
    { id=3, name="banana" } 

People: 
    { id=1, name="user" } 

PeopleFruits 
    { id=1, fruitId = 1, personId = 1, isSelected = 0} 

所有你現在需要更新記錄是得到某人的這個PeopleFruits實體。

PeopleFruits[] personPplFruits = cont.PeopleFruits.Where(pf => pf.personId == 1).ToArray(); 

並根據用戶選擇的內容更新.isSelected屬性。

檢查這篇文章,請:https://www.simple-talk.com/sql/database-administration/how-to-get-database-design-horribly-wrong/

+0

感謝您提供任何建議,我會使用它。對於數據庫架構,你的意思是我需要建立一個完整的水果x人員組合清單嗎?它可以快速增長。 – Icycool

+0

這是正確的,但從架構的角度來看,避免在一個普通字符串中存儲多個值...(這是一個不好的測試和使用設計)... – Fabjan

+0

哦,這是一個誤解。在我的情況下,我使用鏈接表(peopleId,fruitId),但我會添加和刪除此鏈接表中的記錄,而不是創建全部併爲其設置標誌。 – Icycool

2

有在EntityFramework.Extended很多有用的功能。它包含批量更新和刪除功能,可以在您的情況下有用,它也消除了在修改實體之前檢索和加載實體的需求,因此它可以提高您未來的性能。

+1

感謝您的回答。但現在我們不考慮將插件添加到現有系統=) – Icycool