Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework EF core是否将值与update语句中的列进行比较?_Entity Framework_.net Core_Asp.net Core 2.0_Asp.net Core 2.1_Ef Core 2.0 - Fatal编程技术网

Entity framework EF core是否将值与update语句中的列进行比较?

Entity framework EF core是否将值与update语句中的列进行比较?,entity-framework,.net-core,asp.net-core-2.0,asp.net-core-2.1,ef-core-2.0,Entity Framework,.net Core,Asp.net Core 2.0,Asp.net Core 2.1,Ef Core 2.0,我有以下代码 var dbContext = Setup.ConfigureDBContext(); var wo = await dbContext.WorkOrders.Where(x => x.WorkOrderID == 88).SingleOrDefaultAsync(); var t = wo.Confidence; wo.ModifiedDateTime = DateTime.UtcNow; wo.Confidence = t; await dbContext.SaveCha

我有以下代码

var dbContext = Setup.ConfigureDBContext();
var wo = await dbContext.WorkOrders.Where(x => x.WorkOrderID == 88).SingleOrDefaultAsync();
var t = wo.Confidence;
wo.ModifiedDateTime = DateTime.UtcNow;
wo.Confidence = t;
await dbContext.SaveChangesAsync();
在上面的查询中,我分配了相同的
置信度
,但更改了
ModifiedDateTime
EF生成以下SQL语句

exec sp_executesql N'SET NOCOUNT ON;
UPDATE [WorkOrders] SET [ModifiedDateTime] = @p0
WHERE [WorkOrderID] = @p1 AND [VersionStamp] = @p2;
SELECT [VersionStamp]
FROM [WorkOrders]
WHERE @@ROWCOUNT = 1 AND [WorkOrderID] = @p1;

',N'@p1 int,@p0 datetime,@p2 varbinary(8)',@p1=88,@p0='2019-10-09 15:33:06.343',@p2=0x0000000000582A52
注意,EF在update语句中不包括
置信度
列。我假设,EF必须将原始值与新值进行比较,如果有更改,则只在update语句中包含这些列

这是正确的假设吗


我问这个问题是因为
WorkOrder
表也有4个nvarchar(max)列。这些列中的数据是长字符串。如果我的假设是正确的,那么EF还必须比较这4列,以决定这些列是否需要包含在更新查询中。而这种比较会更慢,可能会导致性能下降。然后,我可以为这4列创建单独的附属表。

上下文有一个内部更改跟踪器,正如名称所示,它跟踪对实体所做的更改。它不是比较数据库中的内容,它只是记录在代码中修改了值的属性。如果您只更改了一个或几个属性,EF将发出update语句,其中只包含已修改属性的列,但它并没有以智能方式这样做。换句话说,如果您使用与以前相同的值(显式地或通过一些自动方式,如AutoMapper库)修改属性,它也将在update语句中包含该列,尽管实际值保持不变。

上下文有一个内部更改跟踪程序,如名称所示,跟踪对实体所做的更改。它不是比较数据库中的内容,它只是记录在代码中修改了值的属性。如果您只更改了一个或几个属性,EF将发出update语句,其中只包含已修改属性的列,但它并没有以智能方式这样做。换句话说,如果您使用与以前相同的值(显式地或通过一些自动方式,如AutoMapper之类的库)修改属性,它也将在update语句中包含该列,尽管实际值不变。

您的第一个实体是通过上下文获得的,因此,默认情况下,上下文立即开始跟踪它,这意味着您检索的任何实体都将与其原始值的副本一起存储在DbContext中。更改被跟踪实体的特性值时,上下文会将该实体的
EntityState
更改为
Modified
,ChangeTracker会记录旧特性值和新特性值。调用
SaveChanges
时,数据库会生成并执行一条UPDATE语句,因为ChangeTracker会跟踪哪些属性已修改,所以上下文将发出一条SQL语句,只更新那些已更改的属性,它会将其与原始值进行比较,以确定更新的属性

如果您关心特定列,则可以禁用边跟踪边查询:

var item = _context.Employees.Where(x=>x.ID==1).AsNoTracking().FirstOrDefault();
然后告诉上下文您要修改哪个属性,上下文将发出SQL语句更新而不进行比较:

item.Name = "213213";
_context.Attach(item).Property(x => x.Name).IsModified = true;
_context.SaveChanges();

您的第一个实体是由上下文获取的,因此默认情况下,上下文立即开始跟踪它,这意味着您检索的任何实体都将与其原始值的副本一起存储在DbContext中。更改被跟踪实体的特性值时,上下文会将该实体的
EntityState
更改为
Modified
,ChangeTracker会记录旧特性值和新特性值。调用
SaveChanges
时,数据库会生成并执行一条UPDATE语句,因为ChangeTracker会跟踪哪些属性已修改,所以上下文将发出一条SQL语句,只更新那些已更改的属性,它会将其与原始值进行比较,以确定更新的属性

如果您关心特定列,则可以禁用边跟踪边查询:

var item = _context.Employees.Where(x=>x.ID==1).AsNoTracking().FirstOrDefault();
然后告诉上下文您要修改哪个属性,上下文将发出SQL语句更新而不进行比较:

item.Name = "213213";
_context.Attach(item).Property(x => x.Name).IsModified = true;
_context.SaveChanges();

但是上面的代码不包括update语句中的
Confidence
列,即使我在代码中设置了它。我知道EF有变更跟踪器,它在内存中跟踪变更。我的问题更多的是关于比较。我假设追踪器必须比较实体的所有属性值,以了解列是否需要包括,但上面的代码不包括update语句中的
置信度
列,即使我在代码中设置了它。我知道EF有变更跟踪器,它在内存中跟踪变更。我的问题更多的是关于比较。我假设跟踪器必须比较实体的所有属性的值,以知道列是否需要包含