我正在使用实体框架来填充网格控件。有时当我进行更新时,我得到以下错误:
存储更新、插入或删除语句影响了意外的行数(0)。实体可能在加载实体后已被修改或删除。刷新ObjectStateManager条目。
我不知道怎么复制这个。但这可能和我更新的时间间隔有关系。有人见过这个吗,或者有人知道错误消息指的是什么吗?
编辑:不幸的是,我不再有自由重现我在这里遇到的问题,因为我离开了这个项目,不记得我最终是否找到了解决方案,是否有其他开发人员修复了它,或者是否我绕过了它。因此我不能接受任何回答。
我正在使用实体框架来填充网格控件。有时当我进行更新时,我得到以下错误:
存储更新、插入或删除语句影响了意外的行数(0)。实体可能在加载实体后已被修改或删除。刷新ObjectStateManager条目。
我不知道怎么复制这个。但这可能和我更新的时间间隔有关系。有人见过这个吗,或者有人知道错误消息指的是什么吗?
编辑:不幸的是,我不再有自由重现我在这里遇到的问题,因为我离开了这个项目,不记得我最终是否找到了解决方案,是否有其他开发人员修复了它,或者是否我绕过了它。因此我不能接受任何回答。
当前回答
我在使用异步方法时偶尔会得到这个错误。自从我切换到同步方法后就没有发生过。
偶尔错误:
[Authorize(Roles = "Admin")]
[HttpDelete]
[Route("file/{id}/{customerId}/")]
public async Task<IHttpActionResult> Delete(int id, int customerId)
{
var file = new Models.File() { Id = id, CustomerId = customerId };
db.Files.Attach(file);
db.Files.Remove(file);
await db.SaveChangesAsync();
return Ok();
}
一直有效:
[Authorize(Roles = "Admin")]
[HttpDelete]
[Route("file/{id}/{customerId}/")]
public IHttpActionResult Delete(int id, int customerId)
{
var file = new Models.File() { Id = id, CustomerId = customerId };
db.Files.Attach(file);
db.Files.Remove(file);
db.SaveChanges();
return Ok();
}
其他回答
最近,我正在尝试将EF5升级为EF6样本项目。示例项目的表格有十进制(5,2)类型的列。数据库迁移成功完成。但是,初始数据种子产生了异常。
模型:
public partial class Weather
{
...
public decimal TMax {get;set;}
public decimal TMin {get;set;}
...
}
配置错误:
public partial class WeatherMap : EntityTypeConfiguration<Weather>
{
public WeatherMap()
{
...
this.Property(t => t.TMax).HasColumnName("TMax");
this.Property(t => t.TMin).HasColumnName("TMin");
...
}
}
数据:
internal static Weather[] data = new Weather[365]
{
new Weather() {...,TMax = 3.30M,TMin = -12.00M,...},
new Weather() {...,TMax = 5.20M,TMin = -10.00M,...},
new Weather() {...,TMax = 3.20M,TMin = -8.00M,...},
new Weather() {...,TMax = 11.00M,TMin = -7.00M,...},
new Weather() {...,TMax = 9.00M,TMin = 0.00M,...},
};
我发现了问题,播种数据有精度值,但配置没有精度和比例参数。在样本表中用十进制(10,0)定义的TMax和TMin字段。
正确配置:
public partial class WeatherMap : EntityTypeConfiguration<Weather>
{
public WeatherMap()
{
...
this.Property(t => t.TMax).HasPrecision(5,2).HasColumnName("TMax");
this.Property(t => t.TMin).HasPrecision(5,2).HasColumnName("TMin");
...
}
}
我的示例项目运行在:MySql 5.6.14, Devart.Data。MySql, MVC4, .Net 4.5.1, EF6.01
致以最亲切的问候。
我遇到这种情况是因为datetime和datetime2之间不匹配。奇怪的是,在测试人员发现问题之前,它工作得很好。我的Code First模型包括一个DateTime作为主键的一部分:
[Key, Column(Order = 2)]
public DateTime PurchasedDate { get; set; } = (DateTime)SqlDateTime.MinValue;
生成的列是一个datetime列。当调用SaveChanges时,EF生成了以下SQL:
-- Region Parameters
DECLARE @0 Int = 2
DECLARE @1 Int = 25
DECLARE @2 Int = 141051
DECLARE @3 DateTime2 = '2017-07-27 15:16:09.2630000' --(will not equal a datetime value)
-- EndRegion
UPDATE [dbo].[OrganizationSurvey]
SET [OrganizationSurveyStatusId] = @0
WHERE ((([SurveyID] = @1) AND ([OrganizationID] = @2)) AND ([PurchasedDate] = @3))
因为它试图将datetime列与datetime2值匹配,所以没有返回任何结果。我能想到的唯一解决方案是将列更改为datetime2:
[Key, Column(Order = 2, TypeName = "DateTime2")]
public DateTime PurchasedDate { get; set; } = (DateTime)SqlDateTime.MinValue;
我在一个缺少主键并且有一个DATETIME(2,3)列的表上遇到了这个问题(因此实体的“主键”是所有列的组合)…执行插入时,时间戳有一个更精确的时间(2018-03-20 08:29:51.8319154),被截断为(2018-03-20 08:29:51.832),因此对关键字段的查找失败。
如果试图用数据库中不存在的Id更新记录,可能会发生这种情况。
在SqlServer环境中调试这个问题的一种方法是使用SqlServer副本中包含的Sql Profiler,或者如果使用Express版本,可以通过下面的链接从CodePlex免费获得Express Profiler的副本:
表达分析器
通过使用Sql Profiler,您可以访问EF发送到DB的任何内容。就我而言,这相当于:
exec sp_executesql N'UPDATE [dbo].[Category]
SET [ParentID] = @0, [1048] = NULL, [1033] = @1, [MemberID] = @2, [AddedOn] = @3
WHERE ([CategoryID] = @4)
',N'@0 uniqueidentifier,@1 nvarchar(50),@2 uniqueidentifier,@3 datetime2(7),@4 uniqueidentifier',
@0='E060F2CA-433A-46A7-86BD-80CD165F5023',@1=N'I-Like-Noodles-Do-You',@2='EEDF2C83-2123-4B1C-BF8D-BE2D2FA26D09',
@3='2014-01-29 15:30:27.0435565',@4='3410FD1E-1C76-4D71-B08E-73849838F778'
go
我复制粘贴到Sql Server的查询窗口并执行它。可以肯定的是,尽管它运行了,但是0条记录受到了这个查询的影响,因此EF返回了错误。
在我的例子中,问题是由CategoryID引起的。
没有发送到数据库的ID EF标识的CategoryID,因此0条记录受到影响。
这并不是EF的错,而是在视图控制器中错误的空合并“??”语句,将无意义的内容发送到数据层。