更新关系实体

时间:2016-10-11 05:18:31

标签: c# entity-framework

我有一个场景需要一些帮助。

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

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种类型,即{Pop,Rock和Electronic}

案例1:

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

案例2:

我正在将MusicType名称作为字符串。现在,在更新用户实体时,我必须首先获取MusicType.ID,之后我将能够执行此操作:

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

这种情况有更好的方法吗?

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

2 个答案:

答案 0 :(得分:1)

第一个问题:

实际上,这是个人偏好。因为,不希望删除属于该用户的所有行,然后插入它们。我会将从表单发布的集合与存储在数据库中的行进行比较。然后,从数据库中删除那些不再存在于集合中的实体。并且,插入新的。甚至,您可以更新那些修改了一些其他细节的实体。

顺便说一句,您可以使用新发布的EntityGraphOperations实体框架代码优先轻松实现此目的。我是这个产品的作者。我已将其发布在githubcode-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元素渲染所有类型。当用户发布表单时,我得到的是值而不是所选类型的名称。因此,不需要额外的工作。

答案 1 :(得分:1)

首先,您不需要UserMusicType类,您可以将`User class声明为

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

实体框架将在数据库中创建多对多的关系表

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

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

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

因此,您的查询将添加音乐4,删除音乐2。

如果您不依赖于这种关系,那么删除所有用户音乐并再次添加该集合会更容易。

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

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

您不应该依赖音乐名称