简体   繁体   English

对从AutoMapper映射的实体使用AsNoTracking

[英]Use AsNoTracking for entities mapped from AutoMapper

I have a situation where I am mapping DTO -> Database Entity using automapper. 我有一种情况,我正在使用自动映射器映射DTO->数据库实体。

var entityObj = _mapper.Map<REQUESTEXT>(reqDTO);

Then I am using entityObj to update the record in the database. 然后,我正在使用entityObj更新数据库中的记录。

void Update(REQUESTEXT entityObj)
{
    _context.REQUESTEXTs.Attach(entityObj);  <--- Error
    _context.Entry(entityObj).Property(x => x.CUSTOPTIONCD).IsModified = true;
    _context.SaveChanges();
}

When i am trying to attach REQUESTEXT object to context, its giving me an error: 当我尝试将REQUESTEXT对象附加到上下文时,它给我一个错误:

Attaching an entity of type 'A' failed because another entity of the same type already has the same primary key value. 附加类型“ A”的实体失败,因为相同类型的另一个实体已经具有相同的主键值。 This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. 如果图形中的任何实体具有相互冲突的键值,则使用“附加”方法或将实体的状态设置为“不变”或“修改”时,可能会发生这种情况。 This may be because some entities are new and have not yet received database-generated key values. 这可能是因为某些实体是新实体,尚未收到数据库生成的键值。 In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate. 在这种情况下,请使用“添加”方法或“已添加”实体状态来跟踪图形,然后根据需要将非新实体的状态设置为“未更改”或“已修改”。

As per this SO answer: https://stackoverflow.com/a/23228001/1169180 I need to use AsNoTracking() , I am not sure how to use that in AutoMapper ? 按照这个SO答案: https : AsNoTracking()我需要使用AsNoTracking() ,我不确定如何在AutoMapper使用它吗?

Any suggestions? 有什么建议么?

AsNoTracking refers to when the entities are loaded by the context, not Automapper. AsNoTracking指的是何时由上下文而不是由Automapper加载实体。 You are getting the error because at some point in that DbContext's life, it has loaded the entity with that ID and is tracking it. 之所以会收到错误,是因为在DbContext生命的某个时刻,它已使用该ID加载了实体并正在对其进行跟踪。 The option they recommended is to change over your entity loading to use AsNoTracking which effectively tells EF not to track the entity when it is read. 他们建议的选项是将您的实体加载切换为使用AsNoTracking,这可以有效地告诉EF在读取实体时不要跟踪该实体。

An alternative solution to that problem is to check for the existence of the entity in the DbContext's local cache first, and if found, use AutoMapper to map your property changes across to that existing entity, rather than creating a new entity. 解决该问题的另一种方法是先检查DbContext的本地缓存中是否存在该实体,如果找到该实体,则使用AutoMapper将属性更改映射到该现有实体,而不是创建一个新实体。

For example: 例如:

var existingEntity = _context.REQUESTEXTs.Local.SingleOrDefault(x => x.EntityId == reqDTO.EntityId);
if(existingEntity != null)
    mapper.Map(reqDto, existingEntity);
else
{
    var entityObj = _mapper.Map<REQUESTEXT>(reqDTO);    
    _context.REQUESTEXTs.Attach(entityObj);
    _context.Entry(entityObj).Property(x => x.CUSTOPTIONCD).IsModified = true;
} 
_context.SaveChanges();

This checks the local cache for an existing entity, (does not hit DB) and if found, it uses AutoMapper to update it's properties. 这将检查现有实体的本地缓存(不命中数据库),如果找到,则使用AutoMapper更新其属性。 The entity tracking will note the changes, so when SaveChanges is called, the modifications would go through to the DB. 实体跟踪将记录这些更改,因此,在调用SaveChanges时,修改将进入数据库。 If the local cache does not have the entity, then we create a new instance, attach it, mark it as modified, and save. 如果本地缓存中没有该实体,那么我们将创建一个新实例,将其附加,将其标记为已修改,然后保存。

One suggestion that appears to be missing in your example: You should be validating the assumptions that: 您的示例中似乎缺少一个建议:您应该验证以下假设:

  • The ID in your DTO actually does exist in the database before attempting this and 尝试执行此操作之前,DTO中的ID实际上确实存在于数据库中。
  • The record being modified can, and should be editable by the user making this request. 正在修改的记录可以并且应该可以由发出此请求的用户编辑。 and
  • The data being updated is fully validated. 正在更新的数据已完全验证。

If this is a web application /w an accessible Controller action or Web API endpoint, this could be exploitable to allow users to edit records they otherwise should not be able to, or update records in ways they should not be. 如果这是一个Web应用程序/带有可访问的Controller动作或Web API端点,则可以利用此漏洞允许用户编辑原本不应该的记录,或者以不应该的方式更新记录。 (Trust nothing from a client request.) Each request should be validated thoroughly, and any deviation detected should terminate the client session. (不要从客户端请求中获得任何信任。)每个请求都应经过彻底验证,并且检测到的任何偏差都应终止客户端会话。

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

相关问题 使用Entity Framework保存AutoMapper映射的实体集合 - Saving AutoMapper mapped Collections of Entities using Entity Framework Automapper - 从映射集合中排除一些对象 - Automapper - exclude some objects from mapped collection 无法使用AutoMapper与nhibernate解析子实体 - Unable to use AutoMapper to resolver child entities with nhibernate ASP.net MVC - 我应该使用ViewModel中的AutoMapper到Entity Framework实体吗? - ASP.net MVC - Should I use AutoMapper from ViewModel to Entity Framework entities? 实体框架:包含子实体的 AsNoTracking - Entity Framework: AsNoTracking for included child entities Automapper可以使用实体的导航属性从相关实体中提取值 - Can Automapper use an entity's navigation properties to pull values from related entities 使用AutoMapper从数据库加载实体? - Using AutoMapper to load entities from the database? 使用AutoMapper将实体中的数据展平/展平 - Flatten/Unflatten data from Entities to Models with AutoMapper 使用AutoMapper通过DI容器映射未映射的成员 - Use AutoMapper to Map Un-Mapped Members Via a DI Container 如何在服务层中使用 AsNoTracking - How to use AsNoTracking in a service layer
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM