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

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

问题描述

当我在一个独立的场景,并得到来自客户端的DTO我映射到一个实体来保存它,我做到这一点:

  context.Entry(实体).STATE = EntityState.Modified; 
context.SaveChanges();



对于什么是那么 DbSet.Attach(实体)



为什么我应该使用时EntityState.Modified已经高度重视实体的.Attach方法?


解决方案

当你做 context.Entry(实体).STATE = EntityState.Modified; ,你是不是装好实体到的DbContext ,你也标志着整个实体为脏。这意味着,当你做 context.SaveChanges(),EF将产生一个更新语句,将更新的所有的该实体的字段。



这不总是期望的



在另一方面, DbSet.Attach(实体)重视实体上下文没有标记它弄脏。它相当于做 context.Entry(实体).STATE = EntityState.Unchanged;



在安装这种方式,除非你再进行更新下你叫 context.SaveChanges时间实体的属性,(),EF不会生成此实体的数据库更新。



即使你是在做一个更新的实体,如果实体有很多属性(DB列),但你只需要更新一些规划,你会发现它有利做一个 DbSet.Attach(实体),然后只更新需要更新的一些属性。这样做,这样会产生从EF更高效的更新语句。 EF将只更新您修改的属性(相对于 context.Entry(实体).STATE = EntityState.Modified; 这将导致所有属性/列被更新)



相关文章:添加/安装和实体各国



代码示例



让我们假设你有以下实体:



<预类=郎-CS prettyprint-覆盖> 公共类Person
{
公众诠释标识{搞定;组; } //主键
公共字符串名字{获得;组; }
公共字符串名字{获得;组; }
}

如果您的代码如下所示:



<预类=郎-CS prettyprint-覆盖> context.Entry(personEntity).STATE = EntityState.Modified;
context.SaveChanges();



生成看起来像这样的SQL:



<预类=郎-SQL prettyprint-覆盖> 更新个人
SET名字='什么的名字是',
姓氏='不管姓'
,其中n = 123; - 无论ID为。



注意上面的更新语句将如何更新所有列,无论还是你实际上已经改变了。值或不



在此相反,如果你的代码使用了正常的连接是这样的:



<预类= 郎咸平-CS prettyprint-覆盖> context.People.Attach(personEntity); //状态=不变
person.FirstName =约翰; //状态=修改,只有名字属性脏。
context.SaveChanges();



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



<前类=郎-SQL prettyprint-覆盖> 更新个人
SET名字='约翰'
其中id = 123; - 无论ID为。



正如你所看到的,更新语句 更新您连接实体到上下文后实际上改变的值。根据你的表结构,这可能有积极表现的影响。



现在,哪个选项是更好地为您完全取决于你正在尝试做的。


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
person.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(实体)VS DbContext.Entry(实体).STATE = EntityState.Modified的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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