简体   繁体   English

实体框架具有相同密钥的两个不同对象不起作用

[英]Two different objects with same key for entity framework does not work

I am trying to insert object reference in my main object but EntityFramework will complain if I don't use its previously managed object. 我试图在我的主对象中插入对象引用,但如果我不使用以前的托管对象,EntityFramework会抱怨。 I simply want to avoid having a dependency on the dbContext when creating my object. 我只是想避免在创建对象时依赖dbContext。

Simplified example: 简化示例:

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;

Somehow, if the same ApplicationUser has been previously loaded by the context, I get this error: 不知何故,如果上次加载了相同的ApplicationUser,我会收到此错误:

Saving or accepting changes failed because more than one entity of type 'ApplicationUser' have the same primary key value. 保存或接受更改失败,因为“ApplicationUser”类型的多个实体具有相同的主键值。 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. 确保在数据库和Entity Framework模型中正确配置了数据库生成的主键。 Use the Entity Designer for Database First/Model First configuration. 使用实体设计器进行数据库优先/模型优先配置。 Use the 'HasDatabaseGeneratedOption" fluent API or 'DatabaseGeneratedAttribute' for Code First configuration. 使用'HasDatabaseGeneratedOption'流畅API或'DatabaseGeneratedAttribute'进行Code First配置。

How can I avoid this problem? 我该如何避免这个问题? Optimally, I would like to not have to tell the state of that new object. 最理想的是,我不想告诉那个新对象的状态。

If you have an instance where you are only reading data and not modifying it you can use AsNoTracking() this will prevent having an attached instance of the model that your context knows about (it is essentially read only). 如果你有一个实例,你只读取数据而不修改它,你可以使用AsNoTracking()这将阻止你的上下文知道的模型的附加实例(它本质上是只读的)。

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();

Another note is that AsNoTraking() can also save on performance in scenarios where you are only reading data. 另一个注意事项是,AsNoTraking()还可以在您只读取数据的情况下节省性能。


Edit: 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. 编辑:重新阅读并意识到它是ApplicationUser模型而不是电影,但同样的概念应该适用于第一个实例的retreival。


Edit2: EDIT2:

From our comments you could also do the following the prevent needing to do the lookup at all if you already know the ID: 根据我们的评论,您还可以执行以下操作,如果您已经知道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();

if the same ApplicationUser has been previously loaded by the context, I get this error 如果上次加载了相同的ApplicationUser,我会收到此错误

So first check if the ApplicationUser is loaded. 因此,首先检查ApplicationUser是否已加载。

var newId = 2;
var newApplicationUser = db.ApplicationUsers.Local.FirstOrdefault(u => u.Id == newId)
                             ?? new ApplicationUser { Id = newId };
myMovie.Owner = newApplicationUser;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 实体框架核心两个对象作为主键 - Entity Framework Core Two Objects as Primary Key 实体框架6引用同一实体的两个不同集合 - Entity Framework 6 two different collections referring same entity 实体框架Core 2中相同属性的跨域对象的行为不同 - Different behavior across domain objects for same properties in Entity Framework Core 2 实体框架(核心),多次引用同一张表但对象不同 - Entity Framework (Core), multiple refrences to the same table but different objects 如何使用实体框架添加具有相同数据的不同子对象? - How to add different child objects with the same data using Entity Framework? 是否有使用实体框架将同一接口的两个实体合并的解决方法? - Is there a work around for unioning two entities of the same interface using entity framework? 实体框架lambda中具有不同子句的两个联接到同一表 - Two joins with different clauses to same table in Entity Framework lambda 具有相同名称的两个构造函数具有不同的参数实体框架 - Two constructors with same name different parameters entity framework 如何将相同 class 的两个列表拆分为实体框架中的不同表? - How to split two lists of the same class to different tables in Entity Framework? 实体框架代码优先 - 两个具有相同名称但位于不同名称空间的实体 - Entity Framework Code First - two entities with same name but in different namespaces
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM