c# - 通过消息传递服务传输实体对象,对其进行更改并将其附加回来
问题描述
我通过 MassTransit 传输实体对象,更改一些属性并将其返回。这当然涉及后台的序列化/反序列化,由 MassTransit 使用 RabbitMQ 自动完成。
当我尝试附加或更新实体时
_machinesContext.Machines.Update((Machine)machine);
它引发了密钥丢失的期望。
ex = {"Value cannot be null. (Parameter 'key')"}
at System.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)\r\n at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)\r\n at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value)\r\n at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityReferenceMap.TryGet(Object entity, IEntityType entityType, InternalEntityEntry& entry, Boolean throwOnNonUniqueness)\r\n at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.TryGetEntry(Object entity, IEntityType entityType, Boolean throwOnTypeMismatch)\r\n at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.InitialFixup(InternalEntityEntry entry, Boolean fromQuery)\r\n at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.StateChanged(InternalEntityEntry entry, EntityState oldState, Boolean fromQuery)\r\n at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntryNotifier.StateChanged(InternalEntityEntry entry, EntityState oldState, Boolean fromQuery)\r\n at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.FireStateChanged(EntityState oldState)\r\n at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges, Boolean modifyProperties)\r\n at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState entityState, Boolean acceptChanges, Boolean modifyProperties, Nullable`1 forceStateWhenUnknownKey)\r\n at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.PaintAction(EntityEntryGraphNode`1 node)\r\n at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode`1 node, Func`2 handleNode)\r\n at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode`1 node, Func`2 handleNode)\r\n at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.AttachGraph(InternalEntityEntry rootEntry, EntityState targetState, EntityState storeGeneratedWithKeySetTargetState, Boolean forceStateWhenUnknownKey)\r\n at Microsoft.EntityFrameworkCore.DbContext.SetEntityState(InternalEntityEntry entry, EntityState entityState)\r\n at Microsoft.EntityFrameworkCore.DbContext.SetEntityState[TEntity](TEntity entity, EntityState entityState)\r\n at Microsoft.EntityFrameworkCore.DbContext.Update[TEntity](TEntity entity)\r\n at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.Update(TEntity entity)\r\n
只是提到调用的主键.MachineId
不为空,它有一个int
值。
我发现更新对象以通过 再次从上下文中获取它的唯一方法.Find
,然后.CurrentValues.SetValues(transferedObject)
像这样使用:
var existingMachine = await _machinesContext.Machines.FindAsync(machine.MachineId);
_machinesContext.Entry(existingMachine).CurrentValues.SetValues((Machine)machine);
await _machinesContext.SaveChangesAsync();
有没有更好的方法来附加和更新实体?
解决方案
update 方法 它将所有属性放在查询中,即使没有对它们进行任何更改。在后台,对象集的状态已修改。您可以通过反射搜索所有属性,并且只修改已更改的属性。
推荐阅读
- r - 如何标准化为序列中的前一个值
- sql - 使用子查询的输出作为主查询的字段
- r - 在具有很多唯一值的大型数据集中设置 geom_bar 中的宽度和间隙
- javascript - 试图改变css onclick中的不透明度
- google-apps-script - 将从 Google 表格通过电子邮件发送数据的脚本
- java - 检查 Azure 存储帐户中是否启用了安全传输
- c++ - 返回开关的三元运算符
- sql - 在oracle中对带有数字、小数点和文本的varchar2进行排序
- javascript - 无法更改 iOS Safari 上的按钮选择
- java - 尝试使用 notifyDataSetChanged 更新我的 listView 自定义列表适配器但不工作