EF CORE update的几种方式

1.先查询,再修改

实体是通过上下文获得的,因此上下文立即开始对其进行跟踪。 当您更改跟踪实体的属性值时,上下文会将实体的EntityState更改为Modified,并且ChangeTracker记录旧属性值和新属性值。 调用SaveChanges时,数据库将生成并执行UPDATE语句。如果发现修改值和原始值相同时,State是unchanged

  var user = testDbContext.User.Include(a => a.Orders).First(a => a.UserId == 1);
            user.FirstName = "zhang";
            EntityState ss = testDbContext.Entry(user).State;//unchanged
            testDbContext.SaveChanges();
            user.FirstName = "zhang1";
            EntityState ss1 = testDbContext.Entry(user).State;//modifed
            testDbContext.SaveChanges();
var author = context.Authors.First(a => a.AuthorId == 1);
author.FirstName = "Bill";
context.SaveChanges();
exec sp_executesql N'SET NOCOUNT ON;
UPDATE [Authors] SET [FirstName] = @p0
WHERE [AuthorId] = @p1;
SELECT @@ROWCOUNT;
',N'@p1 int,@p0 nvarchar(4000)',@p1=1,@p0=N'Bill'

2.设置 EntityState的状态

   public void updateEntityState()
        {
            User u = new User();
            u.FirstName = "zhang";
            u.UserId = 1;
            testDbContext.Entry(u).State = EntityState.Modified;
            testDbContext.SaveChanges();

        }
 UPDATE[User] SET[DefaultCurrencyCode] = @p0, [FirstName] = @p1, [LastName] = @p2, [SecurityLevel] = @p3
            WHERE[UserId] = @p4;
            SELECT @@ROWCOUNT;

虽然在代码中定义修改两个属性,但是这种方式依然会把没有定义的属性值设置成null.

3.调用EF CORE 的Update() 方法

public void update()
        {
            User u = new User();
            u.DefaultCurrencyCode = "USD";
            u.FirstName = "zhang";
            u.LastName = "feng";
            u.SecurityLevel = 1;
            u.UserId = 1;
            testDbContext.Update(u);
                EntityState ss = testDbContext.Entry(u).State;
            testDbContext.SaveChanges();

        }
           UPDATE[User] SET[DefaultCurrencyCode] = @p0, [FirstName] = @p1, [LastName] = @p2, [SecurityLevel] = @p3
 WHERE[UserId] = @p4;
SELECT @@ROWCOUNT;

 

此方法与显式设置State属性的区别在于,上下文将以Modified状态开始跟踪任何相关实体,从而为每个实体生成UPDATE语句。  如果关系表未分配键值,并且关系实体类不为空,则将其标记为“added”,并生成INSERT语句。这种方式也是会把没有定义的属性值设置成null(will generate SQL to update all properties)

4.Attach

https://blog.csdn.net/xiaomifengmaidi1/article/details/102809224

在实体上使用Attach方法时,其状态将设置为Unchanged,这将导致根本不生成任何数据库命令。 定义了键值的所有其他关联实体类也将设置为“Unchanged”。 如果关系实体类未分配键值,并且关系实体类不为空,则将其标记为“added”。 可以跟踪任何实体类中的任何属性,设置state 为modified

 public void updateAttach()
        {
            User u = new User();
            u.FirstName = "zhang";
            u.UserId = 2;
            testDbContext.Attach(u);
            testDbContext.Entry(u).State = EntityState.Modified;
            testDbContext.SaveChanges();

        }
UPDATE[User] SET[FirstName] = @p0
 WHERE[UserId] = @p1;
SELECT @@ROWCOUNT;

5.TrackGraph

TrackGraph API提供对对象单个实体的访问,并使您能够针对每个实体单独执行自定义代码。 这在处理由不同状态的各种相关实体组成的复杂对象情况下很有用。

 public void updateTrack()
        {
            var u = new User
            {
                UserId = 1,
                FirstName = "William",
                LastName = "Shakespeare"
            };
            u.Orders = new List();
            u.Orders.Add(new Order { Address = "test1",OrderId=1002 });



            testDbContext.ChangeTracker.TrackGraph(u, e => {
                if ((e.Entry.Entity as User) != null)
                {
                    e.Entry.State = EntityState.Unchanged;
                }
                else
                {
                    e.Entry.State = EntityState.Modified;
                }
            });
            testDbContext.SaveChanges();
        }

这这里, testDbContext.ChangeTracker.TrackGraph会循环user下所有的实体类包括自己,所以我们如果不需要update user的话, if ((e.Entry.Entity as User) != null)
                {
                    e.Entry.State = EntityState.Unchanged;
                }

写上这句话,当然这种方式实体类的属性也会全部更新的,数据库表中不能存在Timestamp字段,不然可能需要做一些其他的设置,不然更新不成功

你可能感兴趣的:(EF,CORE)