在实体框架中,Add和Attach之间有什么区别,以及如何解决我的问题

本文关键字:何解决 解决 问题 我的 什么 Add 框架 实体 Attach 之间 区别 | 更新日期: 2023-09-27 17:50:43

我最近开始使用实体框架,检查是否真的需要向数据库添加新记录一直是一件很痛苦的事情。

如果我需要添加到数据库中的实体已经在上面了,我就会知道,因为我在插入它之前会进行查询,如果它存在,那么我会保留该实例,因为我需要在某些关系中使用它。

假设我的实体名称是Book

当一个实体不在数据库中时,问题就来了,而我在数据库中:

Book b = //...
modelContainer.AddToBooks(b);

我可以很容易地做到:

modelContainer.SaveChanges()

每次我添加一个新的实体(无论它是什么实体(,这都会很好,因为当我一次插入一种条目,并检查它是否已经在数据库中时,我不会有重复问题。

但是如果我想避免经常打SaveChanges()怎么办

在这个问题中:是否可以检查一个对象是否已经附加到实体框架中的数据上下文?,这个问题的作者提供了一种方法,在我的情况下对我有帮助,但如果我把对象Add而不是Attaching放到上下文中,它就不起作用。

我的问题(可能是两个,但非常相关(是:Add和Attach之间的区别是什么?我如何解决我的问题

编辑:
这是我遇到的问题的一个例子。

我有一个实体Result,它与另外两个实体有关系:TrainerHorse

我从外部源获取数据,所以我必须手动创建所有实体。

每次我需要插入一个新的Trainer时,我都会这样做:

var trainer = Trainer.CreateTrainer(Id)

然后我查询数据库,看看数据库中是否已经有一个Id的培训师。如果是,那么我将trainer变量替换为数据库中的变量。

如果不是,我可以在这里做两件事:

  • 将培训师连接到上下文(我可以使用密钥检查它是否已经存在(
  • 将培训师添加到上下文中(使用AddToTrainers(...)(

Horse相同。

现在,当我需要创建一个新的Result(包含TrainerHorse(时,我会分配上一个训练器&马到那个结果实例。

我应该在这里做些什么才能将新的Result添加到上下文中?

  • 如果我附加了驯马师/马,那么当我附加结果时,我得到InvalidOperationException,告诉我驯马师已经在对象上下文中了
  • 如果我添加培训师而不是附加它,我会得到另一个错误(现在记不起来了,但它告诉我数据库中已经有培训师了(

重要信息:
第一个错误在附加结果时给出,第二个错误在执行SaveChanges()时给出。

这里我想避免的是每次添加新结果时调用SaveChanges()

在实体框架中,Add和Attach之间有什么区别,以及如何解决我的问题

ObjectContext在内部跟踪所有通过上下文加载、附加或添加的实体。当调用SaveChanges时,数据库中只能修改这些实体。每个这样的实体在CCD_ 23中具有一个CCD_。ObjectStateEntry的主要特性之一是State。状态为枚举类型EntityState,提供以下值:

  • 已添加
  • 已删除
  • 已分离
  • 已修改
  • 未更改

从数据库加载的每个实体都处于Unchanged状态。脱离是一种特殊的状态。在ObjectStateManager中找不到处于分离状态的ObjectStateEntry。但是,如果您向ObjectStateManager请求上下文未跟踪的实体的ObjectStateEntry,它将创建一个具有Detached状态的新ObjectStateEntry

现在AttachAddObject之间的区别:

  • Attach-如果调用此方法,ObjectContext将开始跟踪整个对象图(主实体和所有相关实体(。所有尚未被跟踪的实体都将被设置为Unchanged状态
  • AddObject-如果您调用此方法,ObjectContext也将开始跟踪整个对象图(主实体和所有相关实体(。不同之处在于,所有尚未跟踪的实体都将设置为Added状态(=必须设置为数据库的新对象(

我知道我发这篇文章有点晚了,但我一直在寻找类似的解决方案。。。然后我发现了这篇微软的文章,它可能简洁地回答了OP的大多数问题,并可能帮助未来的SO观众?:

添加/附加和实体状态==(http://msdn.microsoft.com/en-us/data/jj592676.aspx(

来自文章:

本主题将介绍如何将实体添加和附加到上下文,以及实体框架如何在SaveChanges期间处理这些实体。

具体参见该页的最后一节:

插入或更新模式:某些应用程序的常见模式是根据主键的值,将实体添加为新实体(导致数据库插入(或将实体附加为现有实体并将其标记为已修改(导致数据库更新(。