2016-10-11 100 views
2

我有一个场景,我需要一些帮助。更新关系实体

让我们假设有一个用户监听某种类型的音乐。

class User 
{ 
    public virtual List<UserMusicType> Music { get; set; } 
} 

public class UserMusicType 
{ 
    public int ID { get; set; } 
    public MusicType name { get; set; } 
} 

public class MusicType 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
} 

有一种形式,我要求用户检查/选择他听的所有类型的音乐。他选择了3种类型,即{流行,摇滚,电子}

案例1:

现在我想更新的用户实体和插入这些3种新类型。根据我的理解,我需要先删除此用户的任何MusicTypes保存在数据库中,然后再次插入这些新类型。这是一个正确的方法吗?删除所有以前的和插入新的?或者有任何其他方式来做到这一点?

案例2:

我正在MusicType名称作为当然的字符串。现在,在更新用户实体,我得先取后,该MusicType.ID我就可以做到这一点:

user.Music.Add(new UserMusicType() { ID = SOME_ID }); 

是否有此情况下,更好的方法?

我很乐意收到EF有经验的人的回复。我想知道是否有这样做的有效方法。或者即使我的方法/模型完全错误或可以改进。

回答

1

第一个问题:

其实,这是个人喜好。因为,不想删除属于该用户的所有行,然后插入它们。我将比较从表单发布的集合与存储在数据库中的行。然后,从数据库中删除集合中不存在的那些实体。并且,插入新的。即使你可以更新那些修改了一些额外细节的实体。

顺便说一句,你可以很容易地实现这与新发布EntityGraphOperations实体框架代码优先。我是这个产品的作者。我已将它发布在github,code-projectnuget。在InsertOrUpdateGraph方法的帮助下,它会自动将您的实体设置为AddedModified。在DeleteMissingEntities方法的帮助下,您可以删除数据库中存在但不在当前集合中的实体。

// This will set the state of the main entity and all of it's navigational 
// properties as `Added` or `Modified`. 
context.InsertOrUpdateGraph(user) 
     .After(entity => 
     { 
      // And this will delete missing UserMusicType objects. 
      entity.HasCollection(p => p.Music) 
       .DeleteMissingEntities(); 
     }); 

您可以阅读my article on Code-project用一步一步的示范和样本项目是可供下载。

第二个问题:

我不知道在哪个平台上的开发应用程序。但是,通常我会将这些库存储在缓存中,如MusicType。并使用DropDownList元素渲染所有类型。当用户发布表单时,我得到的是值而不是所选类型的名称。所以,不需要额外的工作。

+0

如果我在复选框使用MusicType.ID,任何用户都可以修改它,并键入一些随机id,这将可能永远存在。 EF只会添加那些存在的东西?或者它会添加一个新的ID?我是否必须担心异常? – Waleed

+0

@Waleed如果您已将其状态更改为“已添加”,则会插入新的。但是,更好的方法是检查存储在缓存中的'MusicType'集合中是否存在submiited类型的id。所以,不需要对数据库进行额外的查询。 –

1

首先,你不需要UserMusicType类,你可以声明`User类为

class User 
{ 
    public virtual List<MusicType> Music { get; set; } 
} 

和Entity Framework将在数据库中创建一个多对多的关系表

至于第一个问题,这取决于。如果您在任何其他地方(如付款或审计线索)使用此关系,那么最好的方法是将发布的值与保存的值进行比较,例如:

用户选择音乐1,音乐2,音乐3时间并保存,在这种情况下,将插入3条记录。 用户编辑了他的选择并选择了音乐1,音乐3,音乐4,在这种情况下,您将获得提交的值为1,3,4并检索存储在数据库中的值为1,2,3 然后,您将得到新值,这些值是存在于新值但不在旧值中的项目,在这种情况下,它将为4

您将获得已删除的值,它们存在于旧值中,但不在新值中,在这种情况下,它将是音乐2. 其余的可以忽略。

所以,你的查询将被添加音乐4,删除音乐2.

如果不依赖于关系,那么就比较容易只是删除所有用户的音乐,然后再添加收藏。

至于你的问题的第二部分,我假设你将显示用户的一些chechboxes,你应该使复选框控制的值为MusicType ID,这是将发布到后端和你的内容可以使用它将其链接到用户。 例如:

user.Music.Add(new MusicType{ID=[selected ID ]} 

你不应该依赖于音乐名字

+0

好吧,我不知道EF可以自动创建多对多的表格。如果我在复选框中使用MusicType.ID,任何用户都可以对其进行修改并输入一些可能不存在的随机ID。 EF只会添加那些存在的东西?或者它会添加一个新的ID?我是否必须担心异常? – Waleed

+0

只有具有非常好的HTML知识和一些黑客背景的用户才会这样做,并且您可以先检查数据库中是否存在ID,注意ID在用户界面中不可见,典型的HTML将会是“音乐1” –