与实体框架相同的密钥两个不同对象不起作用 [英] Two different objects with same key for entity framework does not work

查看:207
本文介绍了与实体框架相同的密钥两个不同对象不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想我的主要对象插入对象的引用,但会的EntityFramework抱怨,如果我不使用其之前管理的对象。我只是想避免创建我对象时,其上的DbContext依赖

I am trying to insert object reference in my main object but EntityFramework will complain if I don't use its previously managed object. I simply want to avoid having a dependency on the dbContext when creating my object.

简单的例子:

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已经由上下文以前装,我得到这个错误:

Somehow, if the same ApplicationUser has been previously loaded by the context, I get this error:

保存或接受改变失败,因为类型'ApplicationUser的多个实体有相同的主键值。确保明确设置主键值是唯一的。确保数据库生成的主键是在数据库和实体框架模型正确配置。使用实体设计数据库首先/模型优先配置。使用代码优先配置HasDatabaseGeneratedOption流利的API或'DatabaseGeneratedAttribute。

我怎样才能避免这个问题?理想情况下,我想没有告诉这个新对象的状态。

How can I avoid this problem? Optimally, I would like to not have to tell the state of that new object.

推荐答案

如果你有你在哪里实例仅读取数据,而不是改变它,你可以使用AsNoTrack()这将防止具有上下文知道该模型的附加实例(它本质上是只读)。

If you have an instance where you are only reading data and not modifying it you can use AsNoTrack() this will prevent having an attached instance of the model that your context knows about (it is essentially read only).

虽然它retreived同一对象两次下面的代码应该仍然工作。

The following code should work even though it has retreived the same object twice.

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()还可以节省在情况下,您只能读取数据的表现。

Another note is that AsNoTraking() can also save on performance in scenarios where you are only reading data.

编辑:只是重读,意识到这是ApplicationUser模型,而不是电影,但相同的概念应与一审retreival适用

Just reread and realized it is the ApplicationUser model and not the movie, but the same concept should apply with retreival of the first instance.

EDIT2:

这是我们的看法,你也可以做以下的预防需要做查找在所有如果你已经知道ID:

From our comments you could also do the following the prevent needing to do the lookup at all if you already know the 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();

这篇关于与实体框架相同的密钥两个不同对象不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆