Working With Entity Framework Detached Objects

Detached objects, or objects that are created outside of Entity Framework(EF), don't have automatic tracking enabled, and updating database from detached objects is not hard, but requires extra knowledge of EF. With this post I'd like to spell out different ways of doing it.

Before doing anything else, we must first check the state of an entity. If you are using Code First, an entity would be your POCO class that is mapped to the database table.

To get information about an entity in question, and it's relation to the current DbContext, you call a DbContext.Entry<tentity\> method. It will return a DbEntityEntry<tentity\> object which can be used to check the state and perform additional actions on the entity.

When you create a new instance of a class outside of EF, it will have a detached state because context is not tracking that object.

var customer =newCustomer();var customerEntry = _context.Entry<T>(customer);Debug.Write(customerEntry.State)// EntityState.Detached

If your object is in any state other than EntityState.Detached, that means EF knows about it and tracks it, so you don't need to do anything else, DbContext.SaveChanges() would take care of persisting differences into the database.

When at first I was trying to update database from a detached object I thought that I can simply attach it and set it to be modified.

publicoverridevoidUpdate(T entity){var entry = _context.Entry<T>(entity);if(entry.State==EntityState.Detached){
        _context.Set<T>().Attach(entity);
        entry.State=EntityState.Modified;}}

And that would work, but only if the object with the same key is not already present in the context. And if it does exist, you get a nice error:

An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.

So what do you do when an object is already being tracked by EF and you have a detached object, how do you merge them together?

Fortunately, EF does provide a way to update an existing object from a detached object. There are couple different ways you can do it, and it all depends on the context, and what you know about your object.

Here is the first way you can do it:

Querying Database First And Updating Tracked Object

using(var db =newStoreDbContext()){var existingCart = db.Carts.Find(cartId);if(existingCart !=null){//entity is already in the contextvar attachedEntry = db.Entry(existingCart);
        attachedEntry.CurrentValues.SetValues(newCart);}else{//Since we don't have it in db, this is a simple add.
        db.Cart.Add(newCart);}}

After querying a database and finding a record, we know that EF is already tracking the existing object. We then get an entry object of the tracked entity and call attachedEntry.CurrentValues.SetValues to update it with new values. This method works like an auto mapper and updates scalar properties from the passed in object. Also if the property values is different from the original, it sets the property state to be modified.

That works, but requires an extra database call to get an existing record. There is also a way to do that without an extra query.

Not Performing An Extra Database Call And Checking Local Context

There are times when you know for fact an entity is already in the database. An example would be when a database generated id of your object is not set to zero or default. In that situation you can save an extra call by querying the local context first. If an entity does exist in the local context you perform a similar update with attachedEntry.CurrentValues.SetValues, and if it does not exist, you can modify a state of your detached object to modified, which would attach the object and update the database.

For example, when I know that the cart id is not zero, that means it already exists in the database:

if(newCart.Id>0)// Id already assigned, need to update.{//We query local context first to see if it's there.var attachedEntity = db.Carts.Local.Find(newCart.Id);//We have it in the context, need to update.if(attachedEntity !=null){var attachedEntry = _context.Entry(attachedEntity);
        attachedEntry.CurrentValues.SetValues(newCart);}else{//If it's not found locally, we can attach it by setting state to modified.//This would result in a SQL update statement for all fields//when SaveChanges is called. var entry = db.Entry(newCart);
        entry.State=EntityState.Modified;}}else{//This is a simple add since we don't have it in db.
    db.Cart.Add(newCart);}

There is a small difference when you query the database first. EF knows which values have been modified an only those specific value. On the other hand, when you are blindly attaching modified entity, EF doesn't know what fields have changes and performs an update on all fields.

It Works, But Not Fully...

When you call CurrentValues.SetValues(newCart) it will update all scalar properties on your newCart object and set them to modified. However, navigation properties would not get the same respect. As of today EF does not support of full object graph merging, and leaves that for you to manage on your own. So if you have newCart.Customer navigational property it would not get updated. It's the second most requested feature for EF at the moment, so I think they would add it in the future release.

So for now you have to manually SetValues on all your navigational properties in order for them to be updated. There are also other solutions that people have written that might help with updating a full graph.

Finally, if you object graph is not very large, you can get away with getting DbEntityEntry and calling SetValues on each navigational property. But if you do have a large graph and want something automatic I would try something like GraphDiff first.

转载于:https://www.cnblogs.com/happy-Chen/p/3713983.html

数据库和BI工程师面试题  一.数据库 1.Oracle数据库,视图与表的区别?普通视图与物化视图的区别?物化视图的作用? 2.Oracle数据库,有哪几类索引,分别有什么特点? 3.Union与Union All的区别? 4.对游标的理解?游标的分类?使用方法? 5.如何查找和删除表中的重复数据?给出方法或SQL。 6.不借助第三方工具,怎么查看SQL的执行计划? 7.创建索引有哪些需要注意的要点? 阅读详情

相关推荐

CDR学习笔记——02

这篇写一些高级CDR的架构原理。

... 1016

【NI-DAQmx入门】利用NI MAX进行数据采集入门

很多时候我们没有硬件,但是我们又想验证程序的功能或者查看设备的信息,这时候就需要用到NI MAX提供的创建模拟设备的功能,基本不带FPGA的设备都可以在NI MAX里仿真,比如常见的数据采集设备、示波器、万用表等模块化仪器,如果某些设备不能仿真只能找一个类似的设备代替测试功能。6.如果是需要配置cDAQ机箱,可直接在步骤4中搜索cDAQ机箱,如果您需要添加 C 系列模块,请右键单击新的模拟 cDAQ 机箱,然后单击配置模拟。5.NI-DAQmx模拟设备跟真实的DAQ设备都出现在NI MAX 中的“

weixin_43894265的博客 1万+

3分钟创建智能体

智能体简介会在首页以及名片页展示,需要简洁明了的介绍智能体用途✅优秀示例:最好用第三人称直接说明智能体用途~如:打造生动文案好帮手、专业解梦,探寻梦境奥秘等❌反面教材:简介并未介绍用途、语义含糊。如:今天写点啥、看看你做的梦等以上步骤完成后,点击发布,就能成功创建属于你自己的智能体啦~仅自己可访问(免审):发布后仅开发者本人账号可访问、预览、使用该智能体仅链接可访问:发布后任何人均可通过链接访问、预览、使用该智能体。

soso1968的博客 2084

使用NI MAX创建模拟的NI-DAQmx设备

本文将解释并逐步介绍如何创建模拟NI-DAQmx设备。 如果您想了解功能并测试硬件功能而没有实际存在的硬件,则模拟的NI-DAQmx设备可以复制该设备的相似属性。它是使用NI Measurement and Automation Explorer(MAX)中的NI-DAQmx模拟设备选项创建的,其行为与真实设备相似。某些NI-DAQmx设备无法在MAX中进行仿真。在许多情况下,可以模拟相似的设备来代替无法模拟的设备。但是,请记住,模拟设备可能具有您自己的设备上不可用的功能,这一点非常重要。 1.确认您已经

测控道 1万+

Dify搭建AI测试用例生成器

1、获取产品需求文档2、解读、分析、挖掘需求点,提炼为测试点3、依据测试点,生成详细的测试用例4、输出测试用例1、打开 Dify 控制台,依次点击【工作室】-【ChatFlow】-【创建空白应用】。

十二测试录 1371

【已解决】WorkBuddy 国内版与国际版共存 + 关闭自动更新 教程

本文介绍在Windows系统中同时安装并共存WorkBuddy国内版与国际版的完整方案,通过修改product.json文件关闭启动自动更新,修复缓存配置污染问题,确保两版本互不干扰、数据独立。重点解决因共享身份标识导致的更新源错乱、进程锁冲突及自动覆盖风险,提供命令行备份与修改步骤,并强调手动升级时需避免使用应用内更新功能,以规避平台参数错位缺陷。

人生是一场修行 1501

【NI-DAQmx入门】使用NI MAX 的数据采集任务确认硬件连接图

连接图提供了基本的接线原理图,其中说明了运行特定数据采集任务所需的各种连接。总之 ,连线图是一种快速可靠确认接线线序的方式,但是对于支持多种相同类型传感器的采集卡,接线方式还是以手册为准,比如电流输出型位移传感器。4. 连线图选项卡会根据特定任务和硬件配置自动创建接线图,如下,配置接线盒为SCB-68A后,将会提示接线端配置。另一种方法是通过NI DAQ助手配置,只不过此函数在LabVIEW使用,其功能和MAX里的数据采集任务类似。2.以PXIe-6259为例,创建一个采集电压的任务。

weixin_43894265的博客 4582

华为OD机考双机位A卷 - 流浪地球(Java & Python& JS & C/C++ & GO )

华为OD机考双机位A卷 - 流浪地球(OD上机考试双机位A卷)。提供在线OJ刷题。Java、C++、Python、GO语言、C语言、JavaScript题解,并提供完整思路讲解。

算法大师! 4041

Labview 版本选择与虚拟采集卡创建

最近实验室使用到了National Instruments (美国国家仪器有限公司,简称NI)的采集卡USB-6363 作为外行人,在这里也记录一下自己的学习成果,主要是遇到的一些问题,以及如何去查找手册和一些控件的详解案例。首先需要下载Labview软件,官网为,使用需要收费许可,大家可以自己寻找资源。

weixin_43664319的博客 3369

恒玄BES调试笔记-BES2500如何OTA升级ANC和通透参数

前期量产软件anc参数主要是通过anc工具写入flash中,或者anc total gain通过美格信设备校准写入,对于量产后如果想要更新anc参数,如通透模式参数,则无法更新。 这个时候需要通过OTA升级软件,把相关anc参数内置到软件中,从flash中读取total gain。 1、更新强弱降噪和通透参数,由于涉及到个人参数就不列出来了,主要是改动以下相关参数。 extern struct_anc_cfg * anc_coef_list_50p7k[ANC_COEF_...

leezs的博客 2224

如何学习总线技术

如何学习总线技术 以形象生动的比喻来描绘了总线技术的基本思想,指出了总线的基本分类和总线传输的基本原理,以及在学习过程中应当掌握的最基本的知识,对初学者有起到抛砖引入的作用。 0引言   如果一座只能容一个人来往的独木桥,两端的人都想要过桥,为了不拥挤、阻塞,那我们就得采取有效的办法。比如规定某段时间哪端的人过桥,另一端的人就等着该他过桥的时间段的到来,同时也还可以规定人多时要按先来后到或年

ce123的技术博客 8528

mybatis使用中的一些报错

注意:org.apache.ibatis.binding.BindingException: Type interface org.westos.dao.UserDao is not known to the MapperRegistry. 出现这个问题是因为配置文件不在资源目录中导致maven没有自动加载进来 <build> <resources> ...

Junzizhiai的博客 403

模型预测控制(MPC)解析(二):单输入单输出系统

在上一篇中,为了便于说明,预测控制系统采用单输入单输出系统为例进行设计。由于系统模型使用的是状态空间方程,于是可以很容易的将这种设计方法可以扩展到多输入、多输出系统。

行者无疆的博客 8223

hibernate在分层架构中修改数据(update)时遇到的问题!!

开发软件:Myeclipse 10.0 数据库:oracle 开发人员:1111 问题简单描述:修改数据的时候不能正常修改,要么修改不成功,要么报错 nice,下面就来看看怎么解决这个bug的。 首先,我做的是一个租房网站,进去之后显示的是所有的房屋信息,然后可以对相应的房屋信息进行修改和删除: 让图来解释: 接下来我的思路是,当点击修改的时候,会进入修改房屋信...

穆雄雄的博客 438

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Excel导入遇到的问题An object with the same key already exists in the ObjectStateManager……

我再导入excel的时候,在本地上是好好的,但是部署之后就不对了。 开始以为是路径可能出错,然后特意跟踪了路径发现没问题, 后面写了很多日志记录发现下面那异常: An object with the same key already exists in the ObjectStateManager. The existing object is in the Unchanged state....

weixin_30740581的博客 926

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Hibernate查询,实体类set值会自动更新的解决方案

Hibernate查询出的实体都是持久化对象,如果调用该对象的set方法,那么在事务递交时,Hibernate会把你设置的值自动更新到数据库中。 解决方案一 查询方法添加@Transactional(readOnly = true) 事务设置为只读属性 解决方案二 查询方法添加 @Transactional(propagation = Propagation.NOT_SUPPORTED)不在事务中运行 解决方案三 如果是表关联字段,可以在注解中添加属性updatable = false 例:

weixin_46996126的博客 4385

EntityFramework实体更新操作

  Error Info:“An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key”. Explanation: You must check if an entity ...

weixin_30386713的博客 717

Repository模式中,Update总是失败及其解析

在Repository模式中,我的Update方法总是无法更新实体,这个非常郁闷,Update方法如下: 1: public virtual void Update(T entity) 2: { 3: try 4: { 5: if (entity =...

weixin_33859504的博客 1327

Can not set int field to null value错误解决:

查询数据库记录报错: 错误信息: Can not set int field /*某个类的属性*/ to null value 不能设置int类型的属性为null值 原因就是:数据库中有类型为int的字段未赋值 改了之后,执行成功

YangMay5的博客 9867

entities of type `XXX` can not be updated since they are immutable. Entity ids are [1] 问题排查

Error: Failed to transact block operations: internal constraint violated: entities of type `Gravatar` can not be updated since they are immutable. Entity ids are [1]

gambool的博客 212

C#

An object with the same key already exists in the ObjectStateManager. The existing object is in the Unchanged state. An object can only be added to the ObjectStateManager again if it is in the added s

wensibo的专栏 823

Java异常持久化,在用JPA实现对象持久化的时候 出现以下异常 求解答

当前位置:我的异常网» Java Web开发»在用JPA实现对象持久化的时候 出现以下异常 求解答在用JPA实现对象持久化的时候 出现以下异常 求解答www.myexceptions.net网友分享于:2013-11-21浏览:26次在用JPA实现对象持久化的时候 出现以下错误 求解答严重:Servlet.service()forservletdispatcherthrew...

weixin_39574555的博客 382

An item with the same key has already been added. Key: Pomelo.EntityFrameworkCore.MySql.Infrastructu...

An item with the same key has already been added. Key: Pomelo.EntityFrameworkCore.MySql.Infrastructure.Internal.MySqlOptionsExtension An item with the same key has alread...

weixin_30633949的博客 3634

(二)NI采集卡应用学习:使用NI MAX创建测量任务及常见错误

使用NI MAX创建测量任务 1.打开NI MAX软件,在左侧 设备和接口 中右键新建仿真设备,找到指定型号仪器。 2.在左侧 数据邻居 中右键新建NI-DAQmx任务,采集信号,模拟输入(电压)。 3.进行配置,采集模式选择连续采样,设置待采样数、采样率,接线端选择差分等。 常见错误 DAQmx Error: -200284 尚未获取部分或全部请求的样本。 要等待样本可用,请使用更长的读取超时时间或稍后在程序中读取。 要使样本更快可用,请提高采样率。 如果您的任务使用启动触发器,请确保您的启动触发器配

qq_35893001的博客 1万+

数据库数据修改报错The instance of entity type ‘XXX‘ cannot be tracked

在数据库更新时, 1 首先查找数据库是否包含该项 2 然后更新该项目获添加, 在先查找的时候已经跟踪数据 第二步插入会报错The instance of entity type 'XXX' cannot be tracked

星河队长 3212

无法更新EntitySet-因为它具有DefiningQuery并且没有 <UpdateFunction> 元素存在

I am using Entity Framework 1 with .net 3.5. 我正在将Entity Framework 1与.net 3.5配合使用。 I am doing some

xfxf996的博客 3211

Hibernate 对象状态变化及方法总结

今天写项目在一个方法中update一个对象的时候报出如下错误: org.hibernate.HibernateException: illegally attempted to associate a proxy with two open Sessions 去网上查了下,把update方法换成了merge方法后问题解决。 于是在此把对对象的相关操作和概念总结一下。 首先,在hiberna...

lirenyou的博客 285
上一篇: Attaching detached POCO to EF DbContext - simple and fast
下一篇: Solving the Detached Many-to-Many Problem with the Entity Framework
apple443322
博客等级 码龄10年 0粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值