str*_*ons 312 entity-framework
我正在使用Entity Framework来填充网格控件.有时当我进行更新时,我收到以下错误:
存储更新,插入或删除语句会影响意外的行数(0).自实体加载后,实体可能已被修改或删除.刷新ObjectStateManager条目.
我无法弄清楚如何重现这一点.但它可能与我进行更新的距离有多大关系.有没有人看过这个或有没有人知道错误信息是指什么?
编辑:不幸的是我不再自由地重现我在这里遇到的问题,因为我离开了这个项目并且不记得我是否最终找到了解决方案,如果另一个开发人员修复它,或者我是否解决了这个问题.因此我不能接受任何答案.
小智 385
我遇到了这个问题,这是由实体的ID(密钥)字段未设置引起的.因此,当上下文保存数据时,它找不到ID = 0.确保在update语句中放置一个断点并验证是否已设置实体的ID.
来自Paul Bellora的评论
我有这个确切的问题,因为忘记在.cshtml编辑页面中包含隐藏的ID输入
fyj*_*ham 195
这是一种称为乐观并发的功能的副作用.
不是100%确定如何在实体框架中打开/关闭它,但基本上它告诉你的是,当你从数据库中抓取数据和保存更改时,其他人已经更改了数据(这意味着当你去了保存它0行实际上已更新).在SQL术语中,它们的update查询where子句包含行中每个字段的原始值,如果0行受到影响,它就会知道出错了.
它背后的想法是你不会最终覆盖你的应用程序不知道发生的变化 - 这基本上是.NET在你所有更新中引入的一点安全措施.
如果它是一致的,则可能在你自己的逻辑中发生(EG:你实际上是在选择和更新之间的另一种方法中自己更新数据),但它可能只是两个应用程序之间的竞争条件.
Ben*_*Ben 109
哇,很多答案,但是当我做了一些稍微不同的事情时,我得到了这个错误.
简而言之,如果你创建一个新对象并告诉EF它使用它修改EntityState.Modified它然后会抛出这个错误,因为它在数据库中还不存在.这是我的代码:
MyObject foo = new MyObject()
{
someAttribute = someValue
};
context.Entry(foo).State = EntityState.Modified;
context.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
是的,这看起来很愚蠢,但它之所以产生,是因为foo之前已经创建的问题已经传递给它,现在它只someValue传递给它并创建foo自己.
简单的办法,只是改变EntityState.Modified对EntityState.Added或全行更改为:
context.MyObject.Add(foo);
Run Code Online (Sandbox Code Playgroud)
Len*_*rri 23
我面对同样的惊吓错误...... :)然后我意识到我忘了设置一个
@Html.HiddenFor(model => model.UserProfile.UserId)
对于正在更新的对象的主键!我倾向于忘记这个简单但非常重要的东西!
顺便说一下:HiddenFor适用于ASP.NET MVC.
小智 16
检查您是否忘记了GridView中的"DataKeyNames"属性.在GridView中修改数据时必须使用它
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.datakeynames.aspx
Pur*_*ome 15
问题是由以下两种情况之一引起的: -
Concurrency Mode: Fixed..并且Optimistic Concurrency阻止了数据的保存.IE浏览器.有些人在收到服务器数据和保存服务器数据之间更改了行数据.StoreGeneratedPattern = Computed)并且该行不存在.inn*_*227 11
我得到了同样的错误,因为PK的一部分是一个日期时间列,并且插入的记录使用DateTime.Now作为该列的值.实体框架将以毫秒精度插入值,然后以毫秒精度查找刚刚插入的值.但是,SqlServer将该值四舍五入为第二精度,因此实体框架无法找到毫秒精度值.
解决方案是在插入之前截断DateTime.Now的毫秒数.
我有同样的问题,@ webtrifusion的答案帮助找到了解决方案.
我的模型使用了Bind(Exclude)实体ID 的属性,该属性导致实体ID的值在HttpPost上为零.
namespace OrderUp.Models
{
[Bind(Exclude = "OrderID")]
public class Order
{
[ScaffoldColumn(false)]
public int OrderID { get; set; }
[ScaffoldColumn(false)]
public System.DateTime OrderDate { get; set; }
[Required(ErrorMessage = "Name is required")]
public string Username { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
我有同样的问题,我发现这是由RowVersion引起的,它是null.检查您的Id和RowVersion是否为空.
有关更多信息,请参阅本教程
小智 7
编辑时将实体的id或主键包含在视图中作为隐藏字段
即
@Html.HiddenFor(m => m.Id)
Run Code Online (Sandbox Code Playgroud)
解决了这个问题.
此外,如果您的模型包括未使用的项目也包括它并将其发布到控制器
我也遇到了这个错误.它的问题是由我试图保存到的表上的触发器引起的.触发器使用'INSTEAD OF INSERT',这意味着有0行插入到该表中,因此出错.幸运的是,触发器功能可能不正确,但我想这可能是一个有效的操作,应该以某种方式在代码中处理.希望这有一天可以帮助某人.
从模型优先改为代码优先后,我开始收到此错误.我有多个线程更新数据库,其中一些可能会更新同一行.我不知道为什么我使用模型优先没有问题,假设它使用不同的并发默认值.
为了在一个地方处理它,知道它可能发生的条件,我在我的DbContext类中添加了以下重载:
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
public class MyDbContext: DbContext {
...
public int SaveChanges(bool refreshOnConcurrencyException, RefreshMode refreshMode = RefreshMode.ClientWins) {
try {
return SaveChanges();
}
catch (DbUpdateConcurrencyException ex) {
foreach (DbEntityEntry entry in ex.Entries) {
if (refreshMode == RefreshMode.ClientWins)
entry.OriginalValues.SetValues(entry.GetDatabaseValues());
else
entry.Reload();
}
return SaveChanges();
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后SaveChanges(true)在适用的地方打电话.
您需要明确包含主键的BoundField.如果您不希望用户看到主键,则必须通过css将其隐藏:
<asp:BoundField DataField="Id_primary_key" ItemStyle-CssClass="hidden"
HeaderStyle-CssClass="hidden" />
Run Code Online (Sandbox Code Playgroud)
'hidden'是css中的一个类,它的显示设置为'none'.
我在一个缺少主键并且有一个 DATETIME(2, 3) 列的表上遇到了这个问题(所以实体的“主键”是所有列的组合)......执行插入时时间戳有更精确的时间 (2018-03-20 08:29:51.8319154) 被截断为 (2018-03-20 08:29:51.832) 因此关键字段的查找失败。
只需确保表和表单都有主键和 edmx 更新。
我发现更新期间的任何错误通常是因为: - 表中没有主键 - 编辑视图/表单中没有主键(例如@Html.HiddenFor(m=>m.Id)
我也有这个错误。在某些情况下,实体可能不知道您正在使用的实际数据库上下文,或者模型可能不同。为此,设置:EntityState.Modified; 到 EntityState.Added;
去做这个:
if (ModelState.IsValid)
{
context.Entry(yourModelReference).State = EntityState.Added;
context.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
这将确保实体知道您正在使用或添加您正在使用的状态。此时需要设置所有正确的模型值。小心不要丢失可能在后台进行的任何更改。
希望这可以帮助。
@Html.HiddenFor(model => model.RowVersion)
Run Code Online (Sandbox Code Playgroud)
我的rowversion为null,因此不得不将其添加到解决了我的问题的视图中
[DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)]在我的案例中,这条线就行了:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int? SomeNumber { get; set; }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
312791 次 |
| 最近记录: |