c# – 实体框架具有相同键的两个不同对象不起作用

前端之家收集整理的这篇文章主要介绍了c# – 实体框架具有相同键的两个不同对象不起作用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图在我的主要对象中插入对象引用,但如果我不使用以前管理的对象,EntityFramework将会抱怨.我只是想避免在创建我的对象时依赖于dbContext.

简化示例:

class Movie {
    public ApplicationUser Owner { get;set; }
}

var myMovie = db.Movies.FirstOrDefault(m,m => m.Id = 1);
myMovie.Owner = new ApplicationUser { Id = 2 };

// I have to attach or change its state,otherwise,EF will complain the object is not complete
db.Entry(myMovie.Owner).State = EntityState.Unchanged;

不知何故,如果相同的ApplicationUser先前已经被上下文加载,我得到这个错误

Saving or accepting changes Failed because more than one entity of type ‘ApplicationUser’ have the same primary key value. Ensure that explicitly set primary key values are unique. Ensure that database-generated primary keys are configured correctly in the database and in the Entity Framework model. Use the Entity Designer for Database First/Model First configuration. Use the ‘HasDatabaseGeneratedOption” fluent API or ‘DatabaseGeneratedAttribute’ for Code First configuration.

如何避免这个问题?最好的,我不想告诉这个新对象的状态.

解决方法

如果你有一个实例,你只是在读取数据,而不是修改它,你可以使用AsNoTrack()这将阻止拥有你的上下文知道的模型的附加实例(它本质上只读).

以下代码应该可以工作,即使它已经撤回了相同的对象两次.

var myMovieReadOnly = db.Movies.AsNoTracking().FirstOrDefault(m,m => m.Id = 1);

var myMovie = db.Movies.FirstOrDefault(m,m => m.Id = 1);
myMovie.Owner = new ApplicationUser { Id = 2 };

db.SaveChanges();

另一个注意事项是,AsNoTraking()还可以在您只读取数据的情况下节省性能.

编辑:只是重读并意识到它是ApplicationUser模型,而不是电影,但同样的概念应该适用于第一个实例的retreival.

EDIT2:

从我们的评论中,您还可以执行以下操作,如果您已经知道ID,则可以防止需要执行查找:

class Movie {
    public int OwnerId { get;set; }
    public ApplicationUser Owner { get;set; }
}

var myMovie = db.Movies.FirstOrDefault(m,m => m.Id = 1);
myMovie.OwnerId = 2;
db.SaveChanges();

猜你在找的C#相关文章