Entity Framework Core有没有简单的方法来防止更新子实体或父实体?

huangapple go评论67阅读模式
英文:

Does Entity Framework Core have a simple way of preventing the update of child or parent entities?

问题

我正在尝试编写一个UpdateStatus方法,该方法仅在保存对数据库的更改时更新实体的Status字段。如果实体中的任何其他字段发生了更改,我不希望将这些更改保存到数据库中。对于实体自己的字段来说,这相对简单,可以使用以下方式:

using (var context = new DataAccessContext())
{
    context.Attach(entity);
    context.Entry(entity).Property(e => e.StatusCode).IsModified = true;
    context.SaveChanges();
}

然而,我发现如果通过实体的导航属性可达的任何相关实体在没有设置关键值的情况下会被插入。所以,如果某个调用代码将新的Child实体添加到entity.Children中,并且Child实体的ChildId属性为0,那么Child将被插入到数据库中。

在EF Core中是否有一种简单的方法来避免插入相关实体?

我找到了一个旧的StackOverflow帖子,显示了如何在预-Core Entity Framework中执行此操作:https://stackoverflow.com/questions/25441027/how-do-i-stop-entity-framework-from-trying-to-save-insert-child-objects 然而,那个答案涉及循环遍历每个相关实体。在EF Core中是否有更简单的方法?

我之所以寻找更简单的方法,是因为我的实体层次结构深度为5层。我发现仅分离实体的直接子级是不够的。您必须使用嵌套循环来分离孙子、曾孙等。如果您仅分离直接子级,它们将不会被插入,但EF Core将尝试插入新的孙子,并且会崩溃,因为它尚未插入其父级。情况会变得非常混乱。

我可以在更新其Status之前从数据库中读取一个实体的新副本,但我试图避免在写入之前进行读取。

英文:

I'm trying to write an UpdateStatus method which will only update the Status field of an entity when I save changes to the database. If any other fields in the entity have changed I don't want to save those changes to the database. That is simple enough for the entity's own fields, using:

using (var context = new DataAccessContext())
{
    context.Attach(entity);
    context.Entry(entity).Property(e => e.StatusCode).IsModified = true;
    context.SaveChanges();
}

However, I've discovered that any related entity reachable via a navigation property of the entity I'm setting the status of will be inserted if that related entity does not have a key value set. So if a new Child entity is added to entity.Children by some calling code, and the Child entity ChildId property is 0, that Child will be inserted into the database.

Is there any easy way in EF Core to avoid inserting related entities?

I've found an old StackOverflow post that shows how to do it in the pre-Core Entity Framework: https://stackoverflow.com/questions/25441027/how-do-i-stop-entity-framework-from-trying-to-save-insert-child-objects However, that answer involves looping over every related entity. Is there an easier way in EF Core?

The reason I'm looking for an easier way is that my hierarchy of entities is 5 layers deep. And I've found that it's not enough to detach just the immediate children of an entity. You have to use nested loops to detach the grandchildren, the great-grandchildren, etc. If you only detach the immediate children they won't be inserted but EF Core will attempt to insert new grandchildren and will crash and burn because it hasn't inserted their parents. It gets pretty messy.

I could just read a fresh copy of an entity from the database before updating its Status but I'm trying to avoid having to do a read before I write.

答案1

得分: 3

你所询问的在EF Core中相当简单。如果你不希望EF Core更改跟踪器操作处理相关数据,可以设置EntityEntry.State,而不是调用DbContext/DbSet方法,如AttachAddUpdateRemove等。

这个行为与EF6不同,其中方法和状态设置是一样的,部分在保存相关数据 - 添加新实体图文档主题中提到:

>提示
>
>使用EntityEntry.State属性来设置单个实体的状态。例如,context.Entry(blog).State = EntityState.Modified

所以在你的示例中,只需替换

context.Attach(entity);

context.Entry(entity).State = EntityState.Unchanged;
英文:

What you are asking is quite simple in EF Core. If you don't want EF Core change tracker operation to process the related data, set the EntityEntry.State rather than calling DbContext / DbSet methods like Attach, Add, Update, Remove etc.

This behavior is different from EF6 where methods and setting state are doing one and the same, and is partially mentioned in the Saving Related Data - Adding a graph of new entities
documentation topic:

>Tip
>
>Use the EntityEntry.State property to set the state of just a single entity. For example, context.Entry(blog).State = EntityState.Modified.

So in your sample, simply replace

context.Attach(entity);

with

context.Entry(entity).State = EntityState.Unchanged;

答案2

得分: 2

Entity Framework Core在查询中会忽略关联,除非你明确地在查询中包含它们。

当将一个具有相关数据/子属性的实体附加到数据库时,这些实体将包含在查询中。

因此,要解决此问题,你只需将这些子属性设置为null,然后EF Core在更新父对象时将忽略子对象。

英文:

> Entity Framework Core ignores relationships unless you explicitly
> include them in queries.

When attaching an entity to the database that has related data/ child properties, those entities will be included in the query.

So to fix this issue all you need to do is set those child properties to null and then EF Core will ignore the child-objects when you're updating the parent-object.

huangapple
  • 本文由 发表于 2020年1月4日 13:03:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/59588050.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定