2015-07-20 55 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