I am using Entity Framework to populate a grid control. Sometimes when I make updates I get the following error:
我使用实体框架来填充网格控件。有时当我进行更新时,会出现以下错误:
Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
存储更新、插入或删除语句会影响未预料到的行数(0)。实体可能已经被修改或删除,因为实体被加载。刷新ObjectStateManager条目。
I can't figure out how to reproduce this. But it might have something to do with how close together I make the updates. Has anyone seen this or does anyone know what the error message refers to?
我想不出怎么复制这个。但这可能与我的更新密切相关。有人见过这个或有人知道错误信息指的是什么吗?
Edit: Unfortunately I am no longer at liberty to reproduce the problem I was having here, because I stepped away from this project and don't remember if I eventually found a solution, if another developer fixed it, or if I worked around it. Therefore I cannot accept any answers.
编辑:不幸的是,我不再*地再现我在这里遇到的问题,因为我离开了这个项目,并且不记得我最终找到了一个解决方案,如果另一个开发人员修复了它,或者我在它周围工作。因此我不能接受任何答案。
45 个解决方案
#1
169
That's a side-effect of a feature called optimistic concurrency.
这就是所谓的乐观并发特性的副作用。
Not 100% sure how to turn it on/off in Entity Framework but basically what it's telling you is that between when you grabbed the data out of the database and when you saved your changes someone else has changed the data (Which meant when you went to save it 0 rows actually got updated). In SQL terms, their update
query's where
clause contains the original value of every field in the row, and if 0 rows are affected it knows something's gone wrong.
不是100%确定如何打开/关闭实体框架之间但基本上它告诉你的是,当你抓住了数据库的数据,当您保存您的更改别人改变了数据(这意味着当你去保存它0行了更新)。在SQL术语中,它们的update查询的where子句包含行中每个字段的原始值,如果0行受到影响,它就知道出了问题。
The idea behind it is that you won't end up overwriting a change that your application didn't know has happened - it's basically a little safety measure thrown in by .NET on all your updates.
它背后的想法是,你不会在你的应用程序不知道的情况下重写你的应用程序——它基本上是由。net在所有更新中抛出的安全措施。
If it's consistent, odds are it's happening within your own logic (EG: You're actually updating the data yourself in another method in-between the select and the update), but it could be simply a race condition between two applications.
如果它是一致的,那么它发生在您自己的逻辑中(例如:您实际上是在选择和更新之间的另一个方法中自己更新数据),但是它可能只是两个应用程序之间的一个竞争条件。
#2
340
I ran into this and it was caused by the entity's ID (key) field not being set. Thus when the context went to save the data, it could not find an ID = 0. Be sure to place a break point in your update statement and verify that the entity's ID has been set.
我遇到了这个问题,它是由于实体的ID (key)字段没有设置而引起的,所以当context去保存数据时,它找不到ID = 0。确保在更新语句中放置一个断点,并验证该实体的ID已被设置。
From Paul Bellora's comment
从保罗Bellora的评论
I had this exact issue, caused by forgetting to include the hidden ID input in the .cshtml edit page
我有一个确切的问题,因为忘记在.cshtml编辑页面中包含隐藏的ID输入。
#3
87
Wow, lots of answers, but I got this error when I did something slightly different that no on else has mentioned.
哇,很多答案,但是当我做了一些不一样的事情时我犯了这个错误。
Long story short, if you create a new object and tell EF that its modified using the EntityState.Modified
then it will throw this error as it doesn't yet exist in the database. Here is my code:
长话短说,如果你创建了一个新的对象,并告诉EF它使用了EntityState来修改它。修改后,它将抛出这个错误,因为它还不存在于数据库中。这是我的代码:
MyObject foo = new MyObject()
{
someAttribute = someValue
};
context.Entry(foo).State = EntityState.Modified;
context.SaveChanges();
Yes, this seems daft, but it arose because the method in question used to have foo
passed to it having been created earlier on, now it only has someValue
passed to it and creates foo
itself.
是的,这看起来很愚蠢,但是它之所以出现,是因为以前使用的方法已经被创建了,现在它只有someValue传递给它并创建foo本身。
Easy fix, just change EntityState.Modified
to EntityState.Added
or change that whole line to:
容易修复,只是改变状态。EntityState修改。添加或更改整行到:
context.MyObject.Add(foo);
#4
22
I was facing this same scaring error... :) Then I realized that I was forgetting to set a
我正面临着同样的恐吓错误……然后我意识到我忘记设置a了。
@Html.HiddenFor(model => model.UserProfile.UserId)
@Html。= > model.UserProfile.UserId HiddenFor(模型)
for the primary key of the object being updated! I tend to forget this simple, but very important thingy!
对于正在更新的对象的主键!我倾向于忘记这个简单但非常重要的东西!
By the way: HiddenFor
is for ASP.NET MVC.
顺便说一下:HiddenFor是ASP。净MVC。
#5
16
Check whether you forgot the "DataKeyNames" attribute in the GridView. it's a must when modifying data within the GridView
检查在GridView中是否忘记了“DataKeyNames”属性。在GridView中修改数据时必须这样做。
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.datakeynames.aspx
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.datakeynames.aspx
#6
14
The issue is caused by either one of two things :-
这个问题是由以下两件事引起的:-。
- You tried to update a row with one or more properties are
Concurrency Mode: Fixed
.. and the Optimistic Concurrency prevented the data from being saved. Ie. some changed the row data between the time you received the server data and when you saved your server data. - 您试图更新一个具有一个或多个属性的行是并发模式:Fixed ..而乐观的并发性阻止了数据被保存。Ie。在接收服务器数据和保存服务器数据时,有些更改了行数据。
- You tried to update or delete a row but the row doesn't exist. Another example of someone changing the data (in this case, removing) in between a retrieve then save OR you're flat our trying to update a field which is not an Identity (ie.
StoreGeneratedPattern = Computed
) and that row doesn't exist. - 您试图更新或删除一行,但该行不存在。另一个更改数据(在本例中是删除)的例子是,在检索之后保存或您是平的,我们试图更新一个不是标识的字段(ie)。StoreGeneratedPattern = Computed),而这一行不存在。
#7
8
I was having same problem and @webtrifusion's answer helped find the solution.
我遇到了同样的问题,@webtrifusion的答案帮助找到了解决方案。
My model was using the Bind(Exclude)
attribute on the entity's ID which was causing the value of the entity's ID to be zero on HttpPost.
我的模型使用了实体ID上的Bind(排除)属性,该属性导致实体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; }
}
}
#8
8
i had the same problem, i figure out that was caused by the RowVersion which was null. Check that your Id and your RowVersion are not null.
我也有同样的问题,我想这是由RowVersion造成的,它是空的。检查您的Id和行版本是否为空。
for more information refer to this tutorial
更多信息请参考本教程。
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application
#9
7
While editing include the id or primary key of the entity as a hidden field in the view
在编辑时,将实体的id或主键包含为视图中的隐藏字段。
ie
即
@Html.HiddenFor(m => m.Id)
that solves the problem.
来解决这个问题。
Also if your model includes non-used item include that too and post that to the controller
同样,如果您的模型包含了非使用项,也包括这个,并将其发布到控制器。
#10
7
I got this same error because part of the PK was a datetime column, and the record being inserted used DateTime.Now as the value for that column. Entity framework would insert the value with millisecond precision, and then look for the value it just inserted also with millisecond precision. However SqlServer had rounded the value to second precision, and thus entity framework was unable to find the millisecond precision value.
我得到了相同的错误,因为PK的一部分是datetime列,并且记录被插入使用的datetime。现在作为这个列的值。实体框架会以毫秒的精度插入值,然后寻找它刚刚插入的值,并以毫秒为精度。然而,SqlServer将该值转到第二个精度,因此实体框架无法找到毫秒精度值。
The solution was to truncate the milliseconds from DateTime.Now before inserting.
解决方案是缩短DateTime的毫秒数。在插入之前。
#11
6
You need to explicitly include a BoundField of the primary key. If you don't want the user to see the primary key, you have to hide it via css:
您需要显式地包含主键的BoundField。如果你不想让用户看到主键,你必须通过css隐藏它:
<asp:BoundField DataField="Id_primary_key" ItemStyle-CssClass="hidden"
HeaderStyle-CssClass="hidden" />
Where 'hidden' is a class in css that has it's display set to 'none'.
“hidden”是css中的一个类,它的显示设置为“none”。
#12
5
I also came across this error. The problem it turned out was caused by a Trigger on the table I was trying to save to. The Trigger used 'INSTEAD OF INSERT' which means 0 rows ever got inserted to that table, hence the error. Luckily in may case the trigger functionality was incorrect, but I guess it could be a valid operation that should somehow be handled in code. Hope this helps somebody one day.
我也遇到过这个错误。问题是,我试图存钱的桌子上的一个触发器引起了这个问题。触发器使用的是“而不是插入”,这意味着有0行被插入到该表中,因此出现了错误。幸运的是,在可能的情况下,触发功能是不正确的,但是我想它可能是一个有效的操作,应该以某种方式在代码中处理。希望有一天能帮到别人。
#13
4
Just make sure table and form both have primary key and edmx updated.
确保表格和表单都有主键和edmx更新。
i found that any errors during update were usually because of: - No primary key in Table - No primary key in Edit view/form (e.g. @Html.HiddenFor(m=>m.Id
)
我发现更新期间出现的任何错误通常都是由于:-没有主键在表中-没有主键在编辑视图/表单(如@Html.HiddenFor(m=> m.d)。
#14
4
I started getting this error after changing from model-first to code-first. I have multiple threads updating a database where some might update the same row. I don't know why I didn't have a problem using model-first, assume that it uses a different concurrency default.
我在从模型- - - - -首先转换到代码- - -开始得到这个错误。我有多个线程更新一个数据库,其中一些可能更新相同的行。我不知道为什么我没有使用model-first的问题,假设它使用了不同的并发性默认值。
To handle it in one place knowing the conditions under which it might occur, I added the following overload to my DbContext class:
要在一个知道可能发生的条件的地方处理它,我在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();
}
}
}
Then called SaveChanges(true)
wherever applicable.
然后调用SaveChanges(true),只要适用。
#15
4
@Html.HiddenFor(model => model.RowVersion)
My rowversion was null, so had to add this to the view which solved my issue
我的rowversion是null,所以必须将这个添加到解决我的问题的视图中。
#16
3
I got that error when I was deleting some rows in the DB (in the loop), and the adding the new ones in the same table.
在删除DB中的一些行(在循环中)时,我得到了这个错误,并且在同一个表中添加了新的行。
The solutions for me was, to dynamicaly create a new context in each loop iteration
我的解决方案是,在每个循环迭代中动态地创建一个新的上下文。
#17
3
I had the same problem. In my case I was trying to update the primary key, which is not allowed.
我遇到了同样的问题。在我的例子中,我试图更新主键,这是不允许的。
#18
3
The line [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)]
did the trick in my case:
在我的案例中,有一个小技巧:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int? SomeNumber { get; set; }
#19
2
If you are trying to create mapping in your edmx file to a "function Imports", this can result this error. Just clear the fields for insert, update and delete that is located in Mapping Details for a given entity in your edmx, and it should work. I hope I made it clear.
如果您试图在您的edmx文件中创建映射到“函数导入”,这会导致这个错误。只需清除位于edmx中给定实体的映射细节中的插入、更新和删除字段,就可以工作了。我希望我讲清楚了。
#20
2
public void Save(object entity)
{
using (var transaction = Connection.BeginTransaction())
{
try
{
SaveChanges();
transaction.Commit();
}
catch (OptimisticConcurrencyException)
{
if (ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Deleted || ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Modified)
this.Refresh(RefreshMode.StoreWins, entity);
else if (ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Added)
Detach(entity);
AcceptAllChanges();
transaction.Commit();
}
}
}
#21
2
I also had this error. There are some situations where the Entity may not be aware of the actual Database Context you are using or the Model may be different. For this, set: EntityState.Modified; to EntityState.Added;
我也有这个错误。有些情况下,实体可能不知道您正在使用的实际数据库上下文,或者模型可能不同。为此,设置:EntityState.Modified;EntityState.Added;
To do this:
要做到这一点:
if (ModelState.IsValid)
{
context.Entry(yourModelReference).State = EntityState.Added;
context.SaveChanges();
}
This will ensure the Entity knows youre using or adding the State youre working with. At this point all the correct Model Values need to be set. Careful not to loose any changes that may have been made in the background.
这将确保实体知道您正在使用或添加您正在使用的状态。此时,需要设置所有正确的模型值。注意不要忽略背景中可能出现的任何更改。
Hope this helps.
希望这个有帮助。
#22
2
This will also happen if you are trying to insert into a unique constraint situation, ie if you can only have one type of address per employer and you try to insert a second of that same type with the same employer, you will get the same problem.
如果你试图插入一个独特的约束条件,也会发生这种情况(如果你只能在每个雇主那里有一种地址,并且你试图在同一个雇主那里插入一种相同类型的地址,你就会遇到同样的问题)。
OR
或
This could also happen if all of the object properties that were assigned to, they were assigned with the same values as they had before.
如果分配给它们的所有对象属性都具有与以前相同的值,这也可能发生。
using(var db = new MyContext())
{
var address = db.Addresses.FirstOrDefault(x => x.Id == Id);
address.StreetAddress = StreetAddress; // if you are assigning
address.City = City; // all of the same values
address.State = State; // as they are
address.ZipCode = ZipCode; // in the database
db.SaveChanges(); // Then this will throw that exception
}
#23
2
Well i have this same issue. But this was due to my own mistake. Actually i was saving an object instead of adding it. So this was the conflict.
我也有同样的问题。但这是我自己的错误造成的。实际上,我在保存一个对象而不是添加它。这就是冲突。
#24
2
One way to debug this problem in an Sql Server environment is to use the Sql Profiler included with your copy of SqlServer, or if using the Express version get a copy of Express Profiler for free off from CodePlex by the following the link below:
在SqlServer环境中调试这个问题的一种方法是使用包含在SqlServer副本中的Sql Profiler,或者使用Express版本从CodePlex获得一个Express Profiler副本,通过以下链接:
表达分析器
By using Sql Profiler you can get access to whatever is being sent by EF to the DB. In my case this amounted to:
通过使用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
I copy pasted this into a query window in Sql Server and executed it. Sure enough, although it ran, 0 records were affected by this query hence the error being returned by EF.
我将它复制到Sql Server中的查询窗口并执行它。当然,尽管它运行了,但是0记录受到了这个查询的影响,因此EF返回了错误。
In my case the problem was caused by the CategoryID.
在我的案例中,问题是由分类id引起的。
There was no CategoryID identified by the ID EF sent to the database hence 0 records being affected.
由于ID EF发送到数据库,所以没有分类标识,因此有0个记录受到影响。
This was not EF's fault though but rather a buggy null coalescing "??" statement up in a View Controller that was sending nonsense down to data tier.
这不是EF的错误,而是一个错误的空合并“??”语句,在一个视图控制器中,它将无意义的信息发送到数据层。
#25
2
None of the above answers quite covered my situation and the solution to it.
以上的回答都没有涵盖我的情况和解决办法。
Code where the error was thrown in MVC5 controller:
在MVC5控制器中抛出错误的代码:
if (ModelState.IsValid)
{
db.Entry(object).State = EntityState.Modified;
db.SaveChanges(); // line that threw exception
return RedirectToAction("Index");
}
I received this exception when I was saving an object off an Edit view. The reason it threw it was because when I went back to save it, I had modified the properties that formed the primary key on the object. Thus, setting its state to Modified didn't make any sense to EF - it was a new entry, not a previously saved one.
当我在编辑视图中保存一个对象时,我收到了这个异常。它抛出的原因是,当我回去保存它时,我已经修改了在对象上形成主键的属性。因此,将其状态设置为修改对EF没有任何意义——这是一个新条目,而不是先前保存的条目。
You can solve this by either A) modifying the save call to Add the object, or B) just don't change the primary key on edit. I did B).
您可以通过修改save调用来添加对象,或者B)只是不要更改编辑的主键。我做了B)。
#26
1
I ran into this using Telerik's RadGrid. I had the primary key as a gridbound column that was set to read only. It would work fine if the column was display="false" but readonly="true" caused the problem. I solved it by having the gridbound column display=false and adding a separate template column for display
我使用了Telerik的RadGrid。我把主键作为一个gridbound列,它只被设置为只读。如果列显示为“false”,则可以正常工作,但是readonly=“true”导致了问题。我通过让gridbound列显示=false来解决它,并添加一个单独的模板列用于显示。
<telerik:GridBoundColumn HeaderText="Shouldnt see" Display="false"
UniqueName="Id" DataField="Id">
</telerik:GridBoundColumn>
<telerik:GridTemplateColumn HeaderText="Id" UniqueName="IdDisplay">
<ItemTemplate>
<asp:Label ID="IDLabel" runat="server"
Text='<%# Eval("Id") %>'></asp:Label>
</ItemTemplate>
</telerik:GridTemplateColumn>
#27
1
Just had the same problem.
只是有同样的问题。
I'm using EF 6, Code First + Migrations. The problem was that our DBA created a constraint on the table that threw the error.
我使用的是EF 6,代码优先+迁移。问题是,我们的DBA在表上创建了一个限制错误的约束。
#28
1
For those of you using AutoMapper If you are updating an entity that has foreign keys to another entity(or entities), make sure all of the foreign entities have their primary key set to database generated (or auto-incremented for MySQL).
对于那些使用AutoMapper的人来说,如果您正在更新一个具有其他实体(或实体)的外键的实体,请确保所有的外部实体都将其主键集设置为数据库生成(或对MySQL自动递增)。
For example:
例如:
public class BuyerEntity
{
[Key]
public int BuyerId{ get; set; }
public int Cash { get; set; }
public List<VehicleEntity> Vehicles { get; set; }
public List<PropertyEntity> Properties { get; set; }
}
Vehicles and Properties are stored in other tables than Buyers. When you add a new buyer, AutoMapper and EF will automatically update the Vehicles and Properties tables so if you don't have auto-increment set up on either of those tables (like I didn't), then you will see the error from the OP's question.
车辆和财产被储存在其他的桌子上,而不是买家。当您添加一个新的买家时,AutoMapper和EF会自动更新车辆和属性表,因此如果您没有在这些表中设置自动增量(比如我没有),那么您将会从OP的问题中看到错误。
#29
1
When the accepted answer said "it won't end up overwriting a change that your application didn't know has happened", I was skeptic because my object was newly created. But then it turns out, there was an INSTEAD OF UPDATE, INSERT- TRIGGER
attached to the table which was updating a calculated column of the same table.
当被接受的回答说“这不会结束你的应用程序不知道的改变”,我怀疑是因为我的对象是新创建的。但结果是,有一个替代的更新,插入触发器附加到表上,这是更新一个计算列的同一张表。
Once I change this to AFTER INSERT, UPDATE
, it was working fine.
一旦我将其更改为插入、更新后,它就可以正常工作了。
#30
1
This happened to me due to a mismatch between datetime and datetime2. Strangely, it worked fine prior to a tester discovering the issue. My Code First model included a DateTime as part of the primary key:
这是由于datetime和datetime2之间的不匹配导致的。奇怪的是,在测试人员发现问题之前,它工作得很好。我的代码第一个模型包括一个DateTime作为主键的一部分:
[Key, Column(Order = 2)]
public DateTime PurchasedDate { get; set; } = (DateTime)SqlDateTime.MinValue;
The generated column is a datetime column. When calling SaveChanges, EF generated the following SQL:
生成的列是一个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))
Because it was trying to match a datetime column with a datetime2 value, it returned no results. The only solution I could think of was to change the column to a datetime2:
因为它试图以datetime2值匹配datetime列,因此没有返回结果。我能想到的唯一解决方案是将列改为datetime2:
[Key, Column(Order = 2, TypeName = "DateTime2")]
public DateTime PurchasedDate { get; set; } = (DateTime)SqlDateTime.MinValue;
#1
169
That's a side-effect of a feature called optimistic concurrency.
这就是所谓的乐观并发特性的副作用。
Not 100% sure how to turn it on/off in Entity Framework but basically what it's telling you is that between when you grabbed the data out of the database and when you saved your changes someone else has changed the data (Which meant when you went to save it 0 rows actually got updated). In SQL terms, their update
query's where
clause contains the original value of every field in the row, and if 0 rows are affected it knows something's gone wrong.
不是100%确定如何打开/关闭实体框架之间但基本上它告诉你的是,当你抓住了数据库的数据,当您保存您的更改别人改变了数据(这意味着当你去保存它0行了更新)。在SQL术语中,它们的update查询的where子句包含行中每个字段的原始值,如果0行受到影响,它就知道出了问题。
The idea behind it is that you won't end up overwriting a change that your application didn't know has happened - it's basically a little safety measure thrown in by .NET on all your updates.
它背后的想法是,你不会在你的应用程序不知道的情况下重写你的应用程序——它基本上是由。net在所有更新中抛出的安全措施。
If it's consistent, odds are it's happening within your own logic (EG: You're actually updating the data yourself in another method in-between the select and the update), but it could be simply a race condition between two applications.
如果它是一致的,那么它发生在您自己的逻辑中(例如:您实际上是在选择和更新之间的另一个方法中自己更新数据),但是它可能只是两个应用程序之间的一个竞争条件。
#2
340
I ran into this and it was caused by the entity's ID (key) field not being set. Thus when the context went to save the data, it could not find an ID = 0. Be sure to place a break point in your update statement and verify that the entity's ID has been set.
我遇到了这个问题,它是由于实体的ID (key)字段没有设置而引起的,所以当context去保存数据时,它找不到ID = 0。确保在更新语句中放置一个断点,并验证该实体的ID已被设置。
From Paul Bellora's comment
从保罗Bellora的评论
I had this exact issue, caused by forgetting to include the hidden ID input in the .cshtml edit page
我有一个确切的问题,因为忘记在.cshtml编辑页面中包含隐藏的ID输入。
#3
87
Wow, lots of answers, but I got this error when I did something slightly different that no on else has mentioned.
哇,很多答案,但是当我做了一些不一样的事情时我犯了这个错误。
Long story short, if you create a new object and tell EF that its modified using the EntityState.Modified
then it will throw this error as it doesn't yet exist in the database. Here is my code:
长话短说,如果你创建了一个新的对象,并告诉EF它使用了EntityState来修改它。修改后,它将抛出这个错误,因为它还不存在于数据库中。这是我的代码:
MyObject foo = new MyObject()
{
someAttribute = someValue
};
context.Entry(foo).State = EntityState.Modified;
context.SaveChanges();
Yes, this seems daft, but it arose because the method in question used to have foo
passed to it having been created earlier on, now it only has someValue
passed to it and creates foo
itself.
是的,这看起来很愚蠢,但是它之所以出现,是因为以前使用的方法已经被创建了,现在它只有someValue传递给它并创建foo本身。
Easy fix, just change EntityState.Modified
to EntityState.Added
or change that whole line to:
容易修复,只是改变状态。EntityState修改。添加或更改整行到:
context.MyObject.Add(foo);
#4
22
I was facing this same scaring error... :) Then I realized that I was forgetting to set a
我正面临着同样的恐吓错误……然后我意识到我忘记设置a了。
@Html.HiddenFor(model => model.UserProfile.UserId)
@Html。= > model.UserProfile.UserId HiddenFor(模型)
for the primary key of the object being updated! I tend to forget this simple, but very important thingy!
对于正在更新的对象的主键!我倾向于忘记这个简单但非常重要的东西!
By the way: HiddenFor
is for ASP.NET MVC.
顺便说一下:HiddenFor是ASP。净MVC。
#5
16
Check whether you forgot the "DataKeyNames" attribute in the GridView. it's a must when modifying data within the GridView
检查在GridView中是否忘记了“DataKeyNames”属性。在GridView中修改数据时必须这样做。
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.datakeynames.aspx
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.datakeynames.aspx
#6
14
The issue is caused by either one of two things :-
这个问题是由以下两件事引起的:-。
- You tried to update a row with one or more properties are
Concurrency Mode: Fixed
.. and the Optimistic Concurrency prevented the data from being saved. Ie. some changed the row data between the time you received the server data and when you saved your server data. - 您试图更新一个具有一个或多个属性的行是并发模式:Fixed ..而乐观的并发性阻止了数据被保存。Ie。在接收服务器数据和保存服务器数据时,有些更改了行数据。
- You tried to update or delete a row but the row doesn't exist. Another example of someone changing the data (in this case, removing) in between a retrieve then save OR you're flat our trying to update a field which is not an Identity (ie.
StoreGeneratedPattern = Computed
) and that row doesn't exist. - 您试图更新或删除一行,但该行不存在。另一个更改数据(在本例中是删除)的例子是,在检索之后保存或您是平的,我们试图更新一个不是标识的字段(ie)。StoreGeneratedPattern = Computed),而这一行不存在。
#7
8
I was having same problem and @webtrifusion's answer helped find the solution.
我遇到了同样的问题,@webtrifusion的答案帮助找到了解决方案。
My model was using the Bind(Exclude)
attribute on the entity's ID which was causing the value of the entity's ID to be zero on HttpPost.
我的模型使用了实体ID上的Bind(排除)属性,该属性导致实体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; }
}
}
#8
8
i had the same problem, i figure out that was caused by the RowVersion which was null. Check that your Id and your RowVersion are not null.
我也有同样的问题,我想这是由RowVersion造成的,它是空的。检查您的Id和行版本是否为空。
for more information refer to this tutorial
更多信息请参考本教程。
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application
#9
7
While editing include the id or primary key of the entity as a hidden field in the view
在编辑时,将实体的id或主键包含为视图中的隐藏字段。
ie
即
@Html.HiddenFor(m => m.Id)
that solves the problem.
来解决这个问题。
Also if your model includes non-used item include that too and post that to the controller
同样,如果您的模型包含了非使用项,也包括这个,并将其发布到控制器。
#10
7
I got this same error because part of the PK was a datetime column, and the record being inserted used DateTime.Now as the value for that column. Entity framework would insert the value with millisecond precision, and then look for the value it just inserted also with millisecond precision. However SqlServer had rounded the value to second precision, and thus entity framework was unable to find the millisecond precision value.
我得到了相同的错误,因为PK的一部分是datetime列,并且记录被插入使用的datetime。现在作为这个列的值。实体框架会以毫秒的精度插入值,然后寻找它刚刚插入的值,并以毫秒为精度。然而,SqlServer将该值转到第二个精度,因此实体框架无法找到毫秒精度值。
The solution was to truncate the milliseconds from DateTime.Now before inserting.
解决方案是缩短DateTime的毫秒数。在插入之前。
#11
6
You need to explicitly include a BoundField of the primary key. If you don't want the user to see the primary key, you have to hide it via css:
您需要显式地包含主键的BoundField。如果你不想让用户看到主键,你必须通过css隐藏它:
<asp:BoundField DataField="Id_primary_key" ItemStyle-CssClass="hidden"
HeaderStyle-CssClass="hidden" />
Where 'hidden' is a class in css that has it's display set to 'none'.
“hidden”是css中的一个类,它的显示设置为“none”。
#12
5
I also came across this error. The problem it turned out was caused by a Trigger on the table I was trying to save to. The Trigger used 'INSTEAD OF INSERT' which means 0 rows ever got inserted to that table, hence the error. Luckily in may case the trigger functionality was incorrect, but I guess it could be a valid operation that should somehow be handled in code. Hope this helps somebody one day.
我也遇到过这个错误。问题是,我试图存钱的桌子上的一个触发器引起了这个问题。触发器使用的是“而不是插入”,这意味着有0行被插入到该表中,因此出现了错误。幸运的是,在可能的情况下,触发功能是不正确的,但是我想它可能是一个有效的操作,应该以某种方式在代码中处理。希望有一天能帮到别人。
#13
4
Just make sure table and form both have primary key and edmx updated.
确保表格和表单都有主键和edmx更新。
i found that any errors during update were usually because of: - No primary key in Table - No primary key in Edit view/form (e.g. @Html.HiddenFor(m=>m.Id
)
我发现更新期间出现的任何错误通常都是由于:-没有主键在表中-没有主键在编辑视图/表单(如@Html.HiddenFor(m=> m.d)。
#14
4
I started getting this error after changing from model-first to code-first. I have multiple threads updating a database where some might update the same row. I don't know why I didn't have a problem using model-first, assume that it uses a different concurrency default.
我在从模型- - - - -首先转换到代码- - -开始得到这个错误。我有多个线程更新一个数据库,其中一些可能更新相同的行。我不知道为什么我没有使用model-first的问题,假设它使用了不同的并发性默认值。
To handle it in one place knowing the conditions under which it might occur, I added the following overload to my DbContext class:
要在一个知道可能发生的条件的地方处理它,我在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();
}
}
}
Then called SaveChanges(true)
wherever applicable.
然后调用SaveChanges(true),只要适用。
#15
4
@Html.HiddenFor(model => model.RowVersion)
My rowversion was null, so had to add this to the view which solved my issue
我的rowversion是null,所以必须将这个添加到解决我的问题的视图中。
#16
3
I got that error when I was deleting some rows in the DB (in the loop), and the adding the new ones in the same table.
在删除DB中的一些行(在循环中)时,我得到了这个错误,并且在同一个表中添加了新的行。
The solutions for me was, to dynamicaly create a new context in each loop iteration
我的解决方案是,在每个循环迭代中动态地创建一个新的上下文。
#17
3
I had the same problem. In my case I was trying to update the primary key, which is not allowed.
我遇到了同样的问题。在我的例子中,我试图更新主键,这是不允许的。
#18
3
The line [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)]
did the trick in my case:
在我的案例中,有一个小技巧:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int? SomeNumber { get; set; }
#19
2
If you are trying to create mapping in your edmx file to a "function Imports", this can result this error. Just clear the fields for insert, update and delete that is located in Mapping Details for a given entity in your edmx, and it should work. I hope I made it clear.
如果您试图在您的edmx文件中创建映射到“函数导入”,这会导致这个错误。只需清除位于edmx中给定实体的映射细节中的插入、更新和删除字段,就可以工作了。我希望我讲清楚了。
#20
2
public void Save(object entity)
{
using (var transaction = Connection.BeginTransaction())
{
try
{
SaveChanges();
transaction.Commit();
}
catch (OptimisticConcurrencyException)
{
if (ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Deleted || ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Modified)
this.Refresh(RefreshMode.StoreWins, entity);
else if (ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Added)
Detach(entity);
AcceptAllChanges();
transaction.Commit();
}
}
}
#21
2
I also had this error. There are some situations where the Entity may not be aware of the actual Database Context you are using or the Model may be different. For this, set: EntityState.Modified; to EntityState.Added;
我也有这个错误。有些情况下,实体可能不知道您正在使用的实际数据库上下文,或者模型可能不同。为此,设置:EntityState.Modified;EntityState.Added;
To do this:
要做到这一点:
if (ModelState.IsValid)
{
context.Entry(yourModelReference).State = EntityState.Added;
context.SaveChanges();
}
This will ensure the Entity knows youre using or adding the State youre working with. At this point all the correct Model Values need to be set. Careful not to loose any changes that may have been made in the background.
这将确保实体知道您正在使用或添加您正在使用的状态。此时,需要设置所有正确的模型值。注意不要忽略背景中可能出现的任何更改。
Hope this helps.
希望这个有帮助。
#22
2
This will also happen if you are trying to insert into a unique constraint situation, ie if you can only have one type of address per employer and you try to insert a second of that same type with the same employer, you will get the same problem.
如果你试图插入一个独特的约束条件,也会发生这种情况(如果你只能在每个雇主那里有一种地址,并且你试图在同一个雇主那里插入一种相同类型的地址,你就会遇到同样的问题)。
OR
或
This could also happen if all of the object properties that were assigned to, they were assigned with the same values as they had before.
如果分配给它们的所有对象属性都具有与以前相同的值,这也可能发生。
using(var db = new MyContext())
{
var address = db.Addresses.FirstOrDefault(x => x.Id == Id);
address.StreetAddress = StreetAddress; // if you are assigning
address.City = City; // all of the same values
address.State = State; // as they are
address.ZipCode = ZipCode; // in the database
db.SaveChanges(); // Then this will throw that exception
}
#23
2
Well i have this same issue. But this was due to my own mistake. Actually i was saving an object instead of adding it. So this was the conflict.
我也有同样的问题。但这是我自己的错误造成的。实际上,我在保存一个对象而不是添加它。这就是冲突。
#24
2
One way to debug this problem in an Sql Server environment is to use the Sql Profiler included with your copy of SqlServer, or if using the Express version get a copy of Express Profiler for free off from CodePlex by the following the link below:
在SqlServer环境中调试这个问题的一种方法是使用包含在SqlServer副本中的Sql Profiler,或者使用Express版本从CodePlex获得一个Express Profiler副本,通过以下链接:
表达分析器
By using Sql Profiler you can get access to whatever is being sent by EF to the DB. In my case this amounted to:
通过使用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
I copy pasted this into a query window in Sql Server and executed it. Sure enough, although it ran, 0 records were affected by this query hence the error being returned by EF.
我将它复制到Sql Server中的查询窗口并执行它。当然,尽管它运行了,但是0记录受到了这个查询的影响,因此EF返回了错误。
In my case the problem was caused by the CategoryID.
在我的案例中,问题是由分类id引起的。
There was no CategoryID identified by the ID EF sent to the database hence 0 records being affected.
由于ID EF发送到数据库,所以没有分类标识,因此有0个记录受到影响。
This was not EF's fault though but rather a buggy null coalescing "??" statement up in a View Controller that was sending nonsense down to data tier.
这不是EF的错误,而是一个错误的空合并“??”语句,在一个视图控制器中,它将无意义的信息发送到数据层。
#25
2
None of the above answers quite covered my situation and the solution to it.
以上的回答都没有涵盖我的情况和解决办法。
Code where the error was thrown in MVC5 controller:
在MVC5控制器中抛出错误的代码:
if (ModelState.IsValid)
{
db.Entry(object).State = EntityState.Modified;
db.SaveChanges(); // line that threw exception
return RedirectToAction("Index");
}
I received this exception when I was saving an object off an Edit view. The reason it threw it was because when I went back to save it, I had modified the properties that formed the primary key on the object. Thus, setting its state to Modified didn't make any sense to EF - it was a new entry, not a previously saved one.
当我在编辑视图中保存一个对象时,我收到了这个异常。它抛出的原因是,当我回去保存它时,我已经修改了在对象上形成主键的属性。因此,将其状态设置为修改对EF没有任何意义——这是一个新条目,而不是先前保存的条目。
You can solve this by either A) modifying the save call to Add the object, or B) just don't change the primary key on edit. I did B).
您可以通过修改save调用来添加对象,或者B)只是不要更改编辑的主键。我做了B)。
#26
1
I ran into this using Telerik's RadGrid. I had the primary key as a gridbound column that was set to read only. It would work fine if the column was display="false" but readonly="true" caused the problem. I solved it by having the gridbound column display=false and adding a separate template column for display
我使用了Telerik的RadGrid。我把主键作为一个gridbound列,它只被设置为只读。如果列显示为“false”,则可以正常工作,但是readonly=“true”导致了问题。我通过让gridbound列显示=false来解决它,并添加一个单独的模板列用于显示。
<telerik:GridBoundColumn HeaderText="Shouldnt see" Display="false"
UniqueName="Id" DataField="Id">
</telerik:GridBoundColumn>
<telerik:GridTemplateColumn HeaderText="Id" UniqueName="IdDisplay">
<ItemTemplate>
<asp:Label ID="IDLabel" runat="server"
Text='<%# Eval("Id") %>'></asp:Label>
</ItemTemplate>
</telerik:GridTemplateColumn>
#27
1
Just had the same problem.
只是有同样的问题。
I'm using EF 6, Code First + Migrations. The problem was that our DBA created a constraint on the table that threw the error.
我使用的是EF 6,代码优先+迁移。问题是,我们的DBA在表上创建了一个限制错误的约束。
#28
1
For those of you using AutoMapper If you are updating an entity that has foreign keys to another entity(or entities), make sure all of the foreign entities have their primary key set to database generated (or auto-incremented for MySQL).
对于那些使用AutoMapper的人来说,如果您正在更新一个具有其他实体(或实体)的外键的实体,请确保所有的外部实体都将其主键集设置为数据库生成(或对MySQL自动递增)。
For example:
例如:
public class BuyerEntity
{
[Key]
public int BuyerId{ get; set; }
public int Cash { get; set; }
public List<VehicleEntity> Vehicles { get; set; }
public List<PropertyEntity> Properties { get; set; }
}
Vehicles and Properties are stored in other tables than Buyers. When you add a new buyer, AutoMapper and EF will automatically update the Vehicles and Properties tables so if you don't have auto-increment set up on either of those tables (like I didn't), then you will see the error from the OP's question.
车辆和财产被储存在其他的桌子上,而不是买家。当您添加一个新的买家时,AutoMapper和EF会自动更新车辆和属性表,因此如果您没有在这些表中设置自动增量(比如我没有),那么您将会从OP的问题中看到错误。
#29
1
When the accepted answer said "it won't end up overwriting a change that your application didn't know has happened", I was skeptic because my object was newly created. But then it turns out, there was an INSTEAD OF UPDATE, INSERT- TRIGGER
attached to the table which was updating a calculated column of the same table.
当被接受的回答说“这不会结束你的应用程序不知道的改变”,我怀疑是因为我的对象是新创建的。但结果是,有一个替代的更新,插入触发器附加到表上,这是更新一个计算列的同一张表。
Once I change this to AFTER INSERT, UPDATE
, it was working fine.
一旦我将其更改为插入、更新后,它就可以正常工作了。
#30
1
This happened to me due to a mismatch between datetime and datetime2. Strangely, it worked fine prior to a tester discovering the issue. My Code First model included a DateTime as part of the primary key:
这是由于datetime和datetime2之间的不匹配导致的。奇怪的是,在测试人员发现问题之前,它工作得很好。我的代码第一个模型包括一个DateTime作为主键的一部分:
[Key, Column(Order = 2)]
public DateTime PurchasedDate { get; set; } = (DateTime)SqlDateTime.MinValue;
The generated column is a datetime column. When calling SaveChanges, EF generated the following SQL:
生成的列是一个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))
Because it was trying to match a datetime column with a datetime2 value, it returned no results. The only solution I could think of was to change the column to a datetime2:
因为它试图以datetime2值匹配datetime列,因此没有返回结果。我能想到的唯一解决方案是将列改为datetime2:
[Key, Column(Order = 2, TypeName = "DateTime2")]
public DateTime PurchasedDate { get; set; } = (DateTime)SqlDateTime.MinValue;