简体   繁体   English

实体框架核心。 如何正确更新相关数据?

[英]Entity Framework Core. How to update the related data properly?

This question is a common one, but I still can't understand how to update the related entity properly? 这个问题很常见,但是我仍然不明白如何正确更新相关实体?

I have the following code: 我有以下代码:

    public async Task<bool> UpdateStepAssignedToLevelAsync(Step step, Guid levelId, int priority = -1)
    {
        var item = await this._context.StepLevels
            .Include(sl => sl.Step)
            .FirstOrDefaultAsync(x => x.StepId == step.Id && x.LevelId == levelId);
        if (item == null)
        {
            return false;
        }

        //this._context.Entry(item).State = EntityState.Detached;
        if (priority > -1)
        {
            item.Priority = priority;
        }

        item.Step = step;

        //this._context.StepLevels.Update(item);
        var rows = await this._context.SaveChangesAsync();
        return rows > 0;
    }

When it runs I'm getting the following error: 运行时,出现以下错误:

InvalidOperationException: The instance of entity type 'Step' cannot be tracked because another instance with the key value '{Id: 35290c18-5b0a-46a5-8f59-8888cf548df5}' is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.

As I understand the entity is being tracked since the select request at the method's start. 据我了解,自方法开始时的select请求以来,正在跟踪实体。 Okay, but when I'm detaching the entity and calling the Update method (see commented lines), the Step entity is not being changed. 好的,但是当我分离实体并调用Update方法(请参见注释行)时,Step实体没有被更改。 But StepLevel does: the priority is changing. 但是StepLevel确实做到了:优先级正在改变。 When I'm trying to call just Update the EF tries to insert the new Step instead of updating the existing. 当我尝试仅调用“更新”时,EF尝试插入新步骤而不是更新现有步骤。

So, could you please advice me, what is the best practicing here? 那么,能否请您告诉我,这里的最佳实践是什么?

Thanks a lot in advance! 在此先多谢!

First, detaching an entity does not detach related entities, so detaching item does not detach the item.Step retrieved with .Include(sl => sl.Step) . 首先,分离实体不会分离相关实体,因此分离item不会分离item.Step通过.Include(sl => sl.Step)检索到。

Second, since you don't want to change the item.Step , but to update the existing Step entity ( x.StepId == step.Id ), and you know that the context is tracking (contains) the corresponding Step entity loaded from the database, you should use the procedure for updating a db entity from a detached entity via Entry(...).CurrentValues.SetValues method. 其次,由于您不想更改item.Step ,而是要更新现有的Step实体( x.StepId == step.Id ),因此您知道上下文正在跟踪(包含)从中加载的相应Step实体。数据库,则应使用该过程通过Entry(...).CurrentValues.SetValues方法从独立实体更新数据库实体。

So remove 所以删除

item.Step = step;

and use the following instead: 并改用以下代码:

this._context.Entry(item.Step).CurrentValues.SetValues(step);

Last note. 最后一点。 When you work with attached entities, there is no need to (should not) use Update method. 使用附加实体时,无需(不应)使用Update方法。 The change tracker will automatically detect the changed property values if any of the entities being tracked. 如果正在跟踪任何实体,则更改跟踪器将自动检测更改的属性值。

The context is tracking the corresponding Step entity loaded from the DB for that reason it is throwing this error. 由于该原因,上下文正在跟踪从数据库加载的相应Step实体,因此会引发此错误。 You can update each Step property - 您可以更新每个Step属性-

public bool UpdateStepAssignedToLevelAsync(Step step, int levelId)
        {
            using(var context = new StackOverFlowDbContext())
            {
                var item = context.StepLevels
                                  .Include(sl => sl.Step)
                                  .FirstOrDefault(x => x.Id == step.Id && x.Id == levelId);
                if (item == null)
                {
                    return false;
                }

                // Updating Name property
                item.Step.Name = step.Name;

                // Other properties can be upadated

                var rows = context.SaveChanges();
                return rows > 0;
            }

        }

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM