DbSet.Attach(entity)vs DbContext.Entry(entity).State = EntityState.Modified [英] DbSet.Attach(entity) vs DbContext.Entry(entity).State = EntityState.Modified

查看:245
本文介绍了DbSet.Attach(entity)vs DbContext.Entry(entity).State = EntityState.Modified的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我处于一个分离的场景,并从客户端获取一个dto,我映射到一个实体来保存它,我这样做:

  context.Entry(entity).State = EntityState.Modified; 
context.SaveChanges();

对于那些 DbSet.Attach(entity)



或者当EntityState.Modified已经附加实体时为什么要使用.Attach方法?

解决方案

当您执行 context.Entry(entity).State = EntityState.Modified; 时,您不仅将实体附加到 DbContext ,您也将整个实体标记为脏。这意味着,当您执行 context.SaveChanges()时,EF将生成一个更新语句,将更新 全部 实体的字段



这并不总是需要。



另一方面, DbSet.Attach(entity)将实体附加到上下文 而不使用 标记为脏。这相当于做$ code> context.Entry(entity).State = EntityState.Unchanged;



附加这种方式,除非您继续更新实体上的属性,否则下次调用 context.SaveChanges()时,EF不会为此实体生成数据库更新。 p>

即使您计划对实体进行更新,如果实体具有很多属性(db列),但您只想更新一些,您可能会发现执行 DbSet.Attach(entity)是有利的,然后只更新需要更新的几个属性。这样做会从EF生成更有效的更新语句。 EF将仅更新您修改的属性(与 context.Entry(entity).State = EntityState.Modified; 相反,这将导致更新所有属性/列) / p>

相关文档:添加/附加和实体国家



代码示例



假设您有以下实体: / p>

  public class Person 
{
public int Id {get;组; } //主键
public string FirstName {get;组; }
public string LastName {get;组;
}

如果你的代码如下所示:

  context.Entry(personEntity).State = EntityState.Modified; 
context.SaveChanges();

生成的SQL将如下所示:

  UPDATE个人
SET FirstName ='无论第一个名字是',
LastName ='任何姓氏'
WHERE Id = 123; - 不管是什么。

注意上述更新语句如何更新所有列,无论您是否实际更改了值



相比之下,如果您的代码使用常规附加如下:

  context.People.Attach(personEntity); // State = Unchanged 
personEntity.FirstName =John; // State = Modified,只有FirstName属性是脏的。
context.SaveChanges();

然后生成的更新语句是不同的:



< pre class =lang-sql prettyprint-override> 更新人
SET FirstName ='John'
WHERE Id = 123; - 不管是什么。

如您所见,更新语句 更新在将实体附加到上下文之后实际更改的值。根据您的表格结构,这可能会产生积极的性能影响。



现在,哪个选项更适合您完全依赖于您正在尝试的内容。 / p>

When I am in a detached scenario and get a dto from the client which I map into an entity to save it I do this:

context.Entry(entity).State = EntityState.Modified;
context.SaveChanges();

For what is then the DbSet.Attach(entity)

or why should I use the .Attach method when EntityState.Modified already attaches the entity?

解决方案

When you do context.Entry(entity).State = EntityState.Modified;, you are not only attaching the entity to the DbContext, you are also marking the whole entity as dirty. This means that when you do context.SaveChanges(), EF will generate an update statement that will update all the fields of the entity.

This is not always desired.

On the other hand, DbSet.Attach(entity) attaches the entity to the context without marking it dirty. It is equivalent to doing context.Entry(entity).State = EntityState.Unchanged;

When attaching this way, unless you then proceed to update a property on the entity, the next time you call context.SaveChanges(), EF will not generate a database update for this entity.

Even if you are planning on making an update to an entity, if the entity has a lot of properties (db columns) but you only want to update a few, you may find it advantageous to do a DbSet.Attach(entity), and then only update the few properties that need updating. Doing it this way will generate a more efficient update statement from EF. EF will only update the properties you modified (in contrast to context.Entry(entity).State = EntityState.Modified; which will cause all properties/columns to be updated)

Relevant documentation: Add/Attach and Entity States.

Code example

Let's say you have the following entity:

public class Person
{
    public int Id { get; set; } // primary key
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

If your code looks like this:

context.Entry(personEntity).State = EntityState.Modified;
context.SaveChanges();

The SQL generated will look something like this:

UPDATE person
SET FirstName = 'whatever first name is',
    LastName = 'whatever last name is'
WHERE Id = 123; -- whatever Id is.

Notice how the above update statement will update all the columns, regardless or whether you've actually changed the values or not.

In contrast, if your code uses the "normal" Attach like this:

context.People.Attach(personEntity); // State = Unchanged
personEntity.FirstName = "John"; // State = Modified, and only the FirstName property is dirty.
context.SaveChanges();

Then the generated update statement is different:

UPDATE person
SET FirstName = 'John'
WHERE Id = 123; -- whatever Id is.

As you can see, the update statement only updates the values that were actually changed after you attached the entity to the context. Depending on the structure of your table, this can have a positive performance impact.

Now, which option is better for you depends entirely on what you are trying to do.

这篇关于DbSet.Attach(entity)vs DbContext.Entry(entity).State = EntityState.Modified的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆