我有点问题。我有一张桌子与一张桌子有三种关系:
public class ResourceAction
{
public int Id { get; set; }
public int ResourceId { get; set; }
public virtual Resource Resource{ get; set; } //main fk
public virtual Resource ResourceBeingSent { get; set; } //reference
public virtual Resource ResponseObject { get; set; } //reference
ResourceAction()
{
ResourceBeingSent = new Resource();
ResponseObject = new Resource();
}
}
现在这两个引用是可选的,我可以通过在删除记录之前删除它们来创建和删除。但是在尝试编辑现有项目时遇到问题。我得到一个约束错误,我通过将其添加到我的数据库上下文中删除了对这两个引用的约束:
modelBuilder.Entity<ResourceAction>()
.HasOptional(f => f.ResourceBeingSent)
.WithMany()
.WillCascadeOnDelete(false);
modelBuilder.Entity<ResourceAction>()
.HasOptional(f => f.ResponseObject)
.WithMany()
.WillCascadeOnDelete(false);
我在这里结束了,我试过改变实体的状态进行修改并传入记录,我也试过传入改变的值我仍然得到错误:
db.Entry(originalResourceAction).CurrentValues.SetValues(vres);
db.Entry(originalResourceAction).State = EntityState.Modified;
db.SaveChanges();
如果有人能指点我为什么可以创建,删除但不能编辑......那就太好了!
我已经包含了堆栈跟踪,基本上它说它受资源表中的外键(这是必需的)约束。 注意用户无法编辑(主)资源外键,在更新过程中不会更改。
构建数据库的EF模式是(它包括为清晰起见而省略的字段)。
CreateTable(
"dbo.ResourceActions",
c => new
{
Id = c.Int(nullable: false, identity: true),
Name = c.String(nullable: false, maxLength: 100),
HttpMethods = c.Int(nullable: false),
ResourceId = c.Int(nullable: false),
Description = c.String(),
ObjectSentIsList = c.Boolean(nullable: false),
ObjectResponseIsList = c.Boolean(nullable: false),
RespondWithObject = c.Boolean(nullable: false),
FriendlyName = c.String(),
Deprecated = c.Boolean(nullable: false),
ResourceBeingSent_Id = c.Int(),
ResponseObject_Id = c.Int(),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.Resources", t => t.ResourceId, cascadeDelete: true)
.ForeignKey("dbo.Resources", t => t.ResourceBeingSent_Id)
.ForeignKey("dbo.Resources", t => t.ResponseObject_Id)
.Index(t => t.ResourceId)
.Index(t => t.ResourceBeingSent_Id)
.Index(t => t.ResponseObject_Id);
编辑添加了整个actionResult
注意之前,我只是传入整个对象,这是我最近尝试传递用户可以修改的位。 (仍然得到相同的错误)。
public ActionResult Edit(ResourceAction resourceAction)
{
if (ModelState.IsValid)
{
ResourceAction originalResourceAction = db.ResourceActions.Include(c => c.Resource).FirstOrDefault( c => c.Id == resourceAction.Id);
ViewResourceAction vres = new ViewResourceAction();
vres.Description = resourceAction.Description;
vres.FriendlyName = resourceAction.FriendlyName;
vres.HttpMethods = resourceAction.HttpMethods;
vres.ObjectResponseIsList = resourceAction.ObjectResponseIsList;
vres.Name = resourceAction.Name.Replace(" ", "_");
vres.ObjectSentIsList = resourceAction.ObjectSentIsList;
vres.RespondWithObject = resourceAction.RespondWithObject;
if (resourceAction.ResourceBeingSent.Id > 0)
{
vres.ResourceBeingSent = db.Resources.Find(resourceAction.ResourceBeingSent.Id);
}
else
{
vres.ResourceBeingSent = null;
}
if (resourceAction.ResponseObject.Id > 0)
{
vres.ResourceBeingSent = db.Resources.Find(resourceAction.ResponseObject.Id);
}
else
{
vres.ResourceBeingSent = null;
}
db.Entry(originalResourceAction).CurrentValues.SetValues(vres);
db.Entry(originalResourceAction).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Edit","Resources", new{id = resourceAction.ResourceId});
}
ViewBag.ResourceId = new SelectList(db.Resources, "Id", "Name", resourceAction.ResourceId);
return View(resourceAction);
我的错误跟踪是:
[SqlException (0x80131904): The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.Resources_dbo._Version_VersionId". The conflict occurred in database "APIEntities-01", table "dbo._Version", column 'Id'.
The statement has been terminated.]
System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) +1767866
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) +5352418
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) +244
System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) +1691
System.Data.SqlClient.SqlDataReader.TryConsumeMetaData() +61
System.Data.SqlClient.SqlDataReader.get_MetaData() +90
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +365
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds) +1406
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite) +177
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) +53
System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) +134
System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) +41
System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) +10
System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<Reader>b__c(DbCommand t, DbCommandInterceptionContext`1 c) +9
System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch(TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed) +72
System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext) +356
System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior) +166
System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) +10
System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.Execute(Dictionary`2 identifierValues, List`1 generatedValues) +234
System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update() +139
[UpdateException: An error occurred while updating the entries. See the inner exception for details.]
System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update() +319
System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.<Update>b__2(UpdateTranslator ut) +9
System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update(T noChangesResult, Func`2 updateFunction) +120
System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update() +77
System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesToStore>b__35() +11
System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction(Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) +288
System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction) +163
System.Data.Entity.Core.Objects.<>c__DisplayClass2a.<SaveChangesInternal>b__27() +22
System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute(Func`1 operation) +164
System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction) +222
System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options) +7
System.Data.Entity.Internal.InternalContext.SaveChanges() +114
[DbUpdateException: An error occurred while updating the entries. See the inner exception for details.]
System.Data.Entity.Internal.InternalContext.SaveChanges() +199
System.Data.Entity.Internal.LazyInternalContext.SaveChanges() +27
System.Data.Entity.DbContext.SaveChanges() +20
RockHopper.Controllers.ResourceActionsController.Edit(ResourceAction resourceAction) in d:\API Manager\RockHopper\Controllers\ResourceActionsController.cs:177
lambda_method(Closure , ControllerBase , Object[] ) +104
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +14
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +157
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +22
System.Web.Mvc.Async.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) +29
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32
System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d() +50
System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +225
System.Web.Mvc.Async.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34
System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +26
System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +100
System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +54
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +39
System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +12
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +28
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +54
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +29
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +54
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +31
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9657896
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
答案 0 :(得分:1)
毒液在构造函数中:
ResourceAction()
{
ResourceBeingSent = new Resource();
ResponseObject = new Resource();
}
您在那里初始化引用属性,这意味着对象将始终以新的Resource
开头,并且永远不会加载现有的对象,更不用说修改了。
删除这些初始化。在代码中添加新的Resource
以创建第一个新对象。加载(Include
)并设置其值,如果你想修改它。
另请参阅:EF codefirst : Should I initialize navigation properties?