【问题标题】:Self-tracking Entity - Tries to insert an unchanged entity when adding to collection自跟踪实体 - 添加到集合时尝试插入未更改的实体
【发布时间】:2011-07-16 04:08:08
【问题描述】:

使用 EF4 自我跟踪实体。

我有一个“用户”实体,其中包含用户可以属于的“组”集合。我想给这个用户添加/删除一些“组”,只给一个组 ID 列表。

    public void UserAddGroups(int userID, List<int> groups)
    {
        var user = Context.Users.Include("Groups").FirstOrDefault(u => u.ID == userID);
        if (user != null)
        {
            // Iterate through the groups that the user already belongs to.
            foreach (var group in user.Groups.ToList())
            {
                // Remove any groups from the user if the new list does not have it.
                if (!groups.Contains(group.ID)) user.Groups.Remove(group);
                // Else remove it from the list of new groups to avoid duplication.
                else groups.Remove(group.ID);
            }
            // Iterate through the group list and add it to the user's list
            // (only a stubby is created)
            foreach (var group in groups) user.Groups.Add(new Group { ID = group }.MarkAsUnchanged());
            Context.Users.ApplyChanges(user);
            Context.SaveChanges();
        }
    }

此方法的结果在Context.SaveChanges() 处引发错误。错误报告“组”实体不允许null 用于Name 属性。

如果我是 INSERTING 新组,这是可以预料的,但这显然不是我想要做的。我该如何解决这个问题?

【问题讨论】:

    标签: entity-framework self-tracking-entities


    【解决方案1】:

    您实际上是在插入。通过创建一个新组并将其添加到您所说的本质上的集合中,现在添加一个新组。您需要先从数据库加载组以激活对其的跟踪。然后将该组添加到用户组集合中。

    amit_g 的解决方案会起作用,但会导致多个数据库调用(每组一个数据库调用)。我会预先加载所有组

    【讨论】:

    • 你是在告诉我 .MarkAsUnchanged 对实体没有任何作用,并且仍然强制插入到上下文中?这似乎更像是一种解决方法,而不是您可以凭直觉做的事情。
    • 嘿,我从来没有设计过它。但它与将 DB 键连接到 Datacontext 有关,它还强制并发。 “直觉地”做某事的问题在于你从系统的机制中抽象出来。在这种情况下,您使用直觉多次访问数据库。性能会受到影响。我看到很多人在使用 ORM 时会犯这个错误。只是因为比喻已经从数据库请求转移到对象请求,并不意味着那些数据库调用不会发生。
    • 对不起,如果我的评论是指责。感谢您的回复,您对抽象的看法是正确的,这可能会导致许多人忘记它仍然需要进行数据库调用。我对 EF 和 STE 还是很陌生。
    • 不用担心。请记住以下 3 条规则:#1:当您执行查询时,您不是在处理客户端上的对象,#2 您不是在处理数据库服务器上的数据(ala Management Studio 查询)。 #3 您正在处理客户端和服务器之间的通信管道。这是一个请求/响应架构(ala HTTP)这些观察结果可能看起来很明显,但经常被遗忘。
    【解决方案2】:

    试试看

    user.Groups.Add(Context.Groups.FirstOrDefault(g => g.ID == group));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-23
      相关资源
      最近更新 更多