Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.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
C# AddOrUpdate导致不正确的外键更新_C#_Entity Framework - Fatal编程技术网

C# AddOrUpdate导致不正确的外键更新

C# AddOrUpdate导致不正确的外键更新,c#,entity-framework,C#,Entity Framework,我遇到与堆栈溢出时报告的错误相同的错误: 简而言之,在我调用AddOrUpdate插入新记录后,如果我随后调用AddOrUpdate更新同一记录,它会抛出异常 例如: State.cs int Id; string Name; City.cs int Id; int StateId; string Name; int Location; // Crud var state = new State { Name = "NY" }; Context.States.AddOrUpdate(p =&

我遇到与堆栈溢出时报告的错误相同的错误:

简而言之,在我调用AddOrUpdate插入新记录后,如果我随后调用AddOrUpdate更新同一记录,它会抛出异常

例如:

State.cs
int Id;
string Name;

City.cs
int Id;
int StateId;
string Name;
int Location;

// Crud
var state = new State { Name = "NY" };
Context.States.AddOrUpdate(p => p.Name, state);
Context.SaveChanges();

// Adds with location equals to 1
var city = new City { Name = "NYC", Location = "1", State = state };
Context.Cities.AddOrUpdate(p => p.Name, city);
Context.SaveChanges();

// Updating the location to 2, leads to EF trying to set StateId to 0
var city = new City { Name = "NYC", Location = "2", State = state };
Context.Cities.AddOrUpdate(p => p.Name, city);
Context.SaveChanges();
抛出异常,表示外键StateId=0

堆栈跟踪:

"The UPDATE statement conflicted with the FOREIGN KEY constraint "FK_dbo.City_dbo.State_StateId". The conflict occurred in database "C:\X\APP_DATA\LOCAL.MDF", table "dbo.State", column 'Id'.
The statement has been terminated."

System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<NonQuery>b__0(DbCommand t, DbCommandInterceptionContext`1 c)
System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.NonQuery(DbCommand command, DbCommandInterceptionContext interceptionContext)
System.Data.Entity.Internal.InterceptableDbCommand.ExecuteNonQuery()
System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.Execute(Dictionary`2 identifierValues, List`1 generatedValues)
System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
UPDATE语句与外键约束“FK\u dbo.City\u dbo.State\u StateId”冲突。冲突发生在数据库“C:\X\APP\u DATA\LOCAL.MDF”、表“dbo.State”、列“Id”中。 声明已被终止。” System.Data.SqlClient.SqlConnection.OneError(SqlException异常,布尔断开连接,操作'1 wrapCloseInAction) System.Data.SqlClient.SqlInternalConnection.OneError(SqlException异常,布尔断开连接,操作'1 wrapCloseInAction) System.Data.SqlClient.TdsParser.ThroweException和Warning(TdsParserStateObject StateObjectStateObj、布尔调用方连接锁、布尔异步关闭) System.Data.SqlClient.TdsParser.TryRun(RunBehavior RunBehavior,SqlCommand cmdHandler,SqlDataReader dataStream,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj,Boolean&dataReady) System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds、RunBehavior、String ResetOptionString) System.Data.SqlClient.SqlCommand.RunExecuteReaderDS(CommandBehavior cmdBehavior、RunBehavior RunBehavior、Boolean returnStream、Boolean async、Int32超时、任务和任务、Boolean asyncWrite、SqlDataReader ds、Boolean describeParameterEncryptionRequest) System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior RunBehavior、布尔返回流、字符串方法、TaskCompletionSource`1完成、Int32超时、任务和任务、布尔异步写入) System.Data.SqlClient.SqlCommand.InternalExecuteOnQuery(TaskCompletionSource`1 completion,String methodName,Boolean sendToPipe,Int32超时,Boolean asyncWrite) System.Data.SqlClient.SqlCommand.ExecuteNonQuery() System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.b_u0(DbCommand t,DbCommandInterceptionContext`1c) System.Data.Entity.Infrastructure.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget目标,Func`3操作,TInterceptionContext拦截Context,执行操作`3,执行操作`3) System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.NonQuery(DbCommand命令,DbCommandInterceptionContext interceptionContext) System.Data.Entity.Internal.InterceptableDbCommand.ExecuteOnQuery() System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.Execute(Dictionary`2 identifierValues,List`1 generatedValues) System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
谢谢

添加或更新
仅用于简单的种子设定操作。在某些情况下,这也会成为一个bug。这是意想不到的行为

这可能与属性值如何从提交的实例(您的
city
变量)复制到从数据库获取的实例有关。显然,只考虑基本属性

在你的陈述之后

var city = new City { Name = "NYC", Location = "2", State = state };
city
将具有
StateId
=0。分配给数据库实例的就是这个值(该实例与
city
不同)

一旦意识到这一点,您可以通过设置
StateId
而不是
State
来解决此问题

但我认为您不应该在常规业务逻辑中使用
AddOrUpdate
。首先,因为它是有车的(或者说是不完整的),我不知道还有什么在等着我。但也因为这是一个相当沉重的方法。它从数据库中获取一个完整的实体,包括跟踪和所有


但通常情况下,如果您想更新实体,很可能您之前已经获取了它,然后在某个过程中更新了它,现在又想再次提交它。即使在N层应用程序(具有序列化/反序列化等)中,也可能仍然具有对象的Id,通过该Id可以确定是否应该插入或更新对象。因此,在大多数情况下,您无需从数据库中重新获取实体,而
AddOrUpdate
将始终执行此操作(如果实体存在)。

您是否也可以为实体类添加代码,请?请给出完整的异常和堆栈跟踪。您是否尝试使用
StateId=state.StateId
而不是那里的
state=state
?这不是错误,因为要设置的正确属性是StateId。State属性是一个导航属性,stateId是City表中引用State表的字段。不确定如何使用它,但请记住AddOrUpdate主要用于种子设定,因此我仅将其用于查找类型表。任何需要关系的东西,我都会按照正常的EF路径,可能会用类似“if(!db.Cities.Any(c=>c.Name==“newyork”)…的东西来包装它,参见