【问题标题】:Entity Attempting to update incorrect table / multiple instances of IEntityChangeTracker issue实体尝试更新不正确的表/多个 IEntityChangeTracker 问题实例
【发布时间】:2015-07-27 14:46:14
【问题描述】:

这可能是一个愚蠢的问题,但无论如何我都去了。

一些事实。

  • 根据我的参考资料,我正在使用实体 6.0.0.0。
  • 我正在访问一个 azure sql db。
  • 该项目基于 mvc 默认模板 thingo。

所以我试图通过以下代码添加到表中。请注意,每次只尝试了 1 条路径,而不是一次全部 3 条或组合。

public User(UserModel userModel)
{
    using (var db = new SqlDogContext())
    {
        // Path 1 this seem like there is a better way but throws an exception anyways
        var sillyModel = new UserModel() { Id = userModel.Id };

        db.UserLibarys.Add(new UserLib {User = sillyModel, Libary = RssLibObject});
        db.SaveChanges();

        db.UserLibarys.Add(new UserLib {User = sillyModel, Libary = KodiLibObject});
        db.SaveChanges();

        db.UserLibarys.Add(new UserLib {User = sillyModel, Libary = SoundCloudLibObject });
        db.SaveChanges();

        db.UserLibarys.Add(new UserLib {User = sillyModel, Libary = SpotifyBridgeObject });
        db.SaveChanges();

        // Path 2 I guess this would be ok
        var sillyModel = new UserModel() { Id = userModel.Id };
        db.UserLibarys.Add(new UserLib { User = sillyModel, Libary = RssLibObject });
        db.UserLibarys.Add(new UserLib { User = sillyModel, Libary = KodiLibObject });
        db.UserLibarys.Add(new UserLib { User = sillyModel, Libary = SoundCloudLibObject });
        db.UserLibarys.Add(new UserLib { User = sillyModel, Libary = SpotifyBridgeObject });
        db.SaveChanges();

        // Path 3 - What i want to use..
        db.UserLibarys.Add(new UserLib { User = userModel, Libary = RssLibObject });
        db.UserLibarys.Add(new UserLib { User = userModel, Libary = KodiLibObject });
        db.UserLibarys.Add(new UserLib { User = userModel, Libary = SoundCloudLibObject });
        db.UserLibarys.Add(new UserLib { User = userModel, Libary = SpotifyBridgeObject });
        db.SaveChanges();

    }
}

我得到以下路径 1 的异常。

    {"Violation of PRIMARY KEY constraint 'PK_dbo.UserModels'. 
     Cannot insert duplicate key in object 'dbo.UserModels'. 
     The duplicate key value is (009d1c33-a3cf-49db-8243-ff8a447eff16).
     \r\nThe statement has been terminated."}

我得到了路径 2 的以下异常。

    An exception of type 'System.Data.Entity.Validation.DbEntityValidationException' occurred in EntityFramework.dll but was not handled in user code

使用我在stackoverflow某处找到的这个。

try
{
    // Your code...
    // Could also be before try if you know the exception occurs in SaveChanges

    db.SaveChanges();
}
catch (DbEntityValidationException e)
{
    foreach (var eve in e.EntityValidationErrors)
    {
        Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
            eve.Entry.Entity.GetType().Name, eve.Entry.State);
        foreach (var ve in eve.ValidationErrors)
        {
            Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                ve.PropertyName, ve.ErrorMessage);
        }
    }
    throw;
}

我收到以下消息

The User field is required.

这对我来说意义不大,因为在我看来,我正在提供它。

我得到以下路径 3 的异常。

    Additional information: An entity object cannot be referenced by multiple instances of IEntityChangeTracker.

这让我很困惑,因为它看起来像是更新了错误的表。 这是我的模型

public class UserLib
{
    [Key]
    public int LibId { get; set; }

    public bool UserEnabled { get; set; }

    [Required]
    public virtual Lib Libary { get; set; }

    [Required]
    public virtual UserModel User { get; set; }
}

public class UserModel
{
    [Key, ForeignKey("ApplicationUser")]
    public string Id { get; set; }

    public virtual UserLib Libary { get; set; }
    public virtual ApplicationUser ApplicationUser { get; set; }
}

public class Lib
{
    public string Name { get; set; }
    public string Logo { get; set; }

    [Key]
    public int LibId { get; set; }

    public virtual UserLib UserLib { get; set; }
}

public class ApplicationUser : IdentityUser
{
    public virtual UserModel MyUserModel { get; set; }
    // plus some other stuff in here that seems non relavent
}

这里是创建用户模型的地方

using (var db = new SqlDogContext())
{ 
     db.UserModels.Add(
        new UserModel()
        {
            Id = currentId
        }
    );

    db.SaveChanges();

    query = from b in db.UserModels
            where b.Id == currentId
            select b;
}


_CurrentUser = new User(query.First());

最终目标是一个用户模型对应一个用户 许多用户库的一个用户模型 并且让 UserLibaries 拥有图书馆数据库的外键。

所以我可能犯了一个菜鸟错误,但任何人都可以看到我的问题:)。

【问题讨论】:

    标签: c# sql asp.net-mvc entity-framework entity


    【解决方案1】:

    您正在尝试设置主键: var sillyModel = new UserModel() { Id = userModel.Id };然后将其存储多次,这是您无法做到的。让实体框架设置主键。另请注意,您不必在每次操作后继续调用 SaveChanges()。您可以执行所有插入操作,然后调用它一次。

    【讨论】:

    • 当我没有定义键时,我遇到了异常,而且目标不是在每次调用后保存更改,这只是我调试路径 3 的过程对我来说是理想的。 UserModel 不是 UserLib 的主键,LibId 是。
    • 但这就是为什么你得到那个例外。您正在创建一个带有 ID(即使不是主键)的新 UserModel 并多次插入它,但实体框架持有对同一实体的引用。您需要执行以下操作: db.UserLibarys.Add(new UserLib {User = new UserModel() { Id = userModel.Id //这不能是主键}, Libary = RssLibObject});
    • 如果Id是UserModel的主键:" var sillyModel = new UserModel() { Id = userModel.Id };"您不止一次插入它。您需要在尝试将其插入 UserLib 之前使用 Id 插入它。所以基本上用 Id 插入它并调用保存更改,然后通过该 Id 从上下文中请求它并将其插入所有这些行中。
    猜你喜欢
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-01
    • 2011-10-12
    相关资源
    最近更新 更多