【问题标题】:Editing an object in Entity Framework 6在 Entity Framework 6 中编辑对象
【发布时间】:2015-10-22 17:44:31
【问题描述】:

我有一个 Employee 对象,其中包含有关 Employee 的大量信息,例如他的登录名、姓名、姓氏、电子邮件地址等。

在检索到员工编辑页面上的所有信息后,我调用以下代码来更新对象:

 public Employee Edit(Employee objEmployee) // Work on EDIT
 {
    var Original = Get(objEmployee.Login);
    _entities.Employees.Add(objEmployee);           
    _entities.SaveChanges();
    return objEmployee;
 }

一旦到达SaveChanges(),我会得到以下信息:

System.Data.Entity.Infrastructure.DbUpdateException was caught
  HResult=-2146233087
  Message=An error occurred while updating the entries. See the inner exception for details.
  Source=EntityFramework
  StackTrace:
       at System.Data.Entity.Internal.InternalContext.SaveChanges()
       at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
       at System.Data.Entity.DbContext.SaveChanges()
       at CRAWebSiteMVC.Models.EntityEmployeeManagerRepository.Edit(Employee objEmployee) in c:\Users\kade\Source\Workspaces\InfoCubedProjects\CRA\CRAWebSiteMVC\Models\Employee\EntityEmployeeManagerRepository.cs:line 26
       at CRAWebSiteMVC.Models.EmployeeManagerService.Edit(Employee objEmployee) in c:\Users\kade\Source\Workspaces\InfoCubedProjects\CRA\CRAWebSiteMVC\Models\Employee\EmployeeManagerService.cs:line 113
  InnerException: System.Data.Entity.Core.UpdateException
       HResult=-2146233087
       Message=An error occurred while updating the entries. See the inner exception for details.
       Source=EntityFramework
       StackTrace:
            at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
            at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.<Update>b__2(UpdateTranslator ut)
            at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update[T](T noChangesResult, Func`2 updateFunction)
            at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update()
            at System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesToStore>b__d()
            at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
            at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction)
            at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClassb.<SaveChangesInternal>b__8()
            at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
            at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction)
            at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options)
            at System.Data.Entity.Internal.InternalContext.SaveChanges()
       InnerException: System.Data.SqlClient.SqlException
            HResult=-2146232060
            Message=Violation of PRIMARY KEY constraint 'PK_EMPLOYEE'. Cannot insert duplicate key in object 'dbo.Employee'.
The statement has been terminated.
            Source=.Net SqlClient Data Provider
            ErrorCode=-2146232060
            Class=14
            LineNumber=1
            Number=2627
            Procedure=""
            Server=MMSDEVNEW\SQL2008
            State=1
            StackTrace:
                 at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
                 at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
                 at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
                 at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
                 at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
                 at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
                 at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
                 at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
                 at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
                 at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<NonQuery>b__0(DbCommand t, DbCommandInterceptionContext`1 c)
                 at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
                 at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.NonQuery(DbCommand command, DbCommandInterceptionContext interceptionContext)
                 at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteNonQuery()
                 at System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.Execute(Dictionary`2 identifierValues, List`1 generatedValues)
                 at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
            InnerException: 

违反主键约束“PK_EMPLOYEE”。无法在对象“dbo.Employee”中插入重复键。

可能是什么原因造成的,我该如何解决?

【问题讨论】:

  • 因为你添加了一个具有相同 ID(PK 值)的新对象,而不是更新现有的
  • 明白了,如何更新现有对象?
  • 您可以使用db.Entry(objEmployee).State = EntityState.Modified; db.SaveChanges();,但我很困惑为什么您使用var Original = Get(objEmployee.Login);(您从不使用它)-您是否打算将值从objEmployee映射到Original然后保存Original?
  • 将其更改为已修改给我以下错误:“附加类型为'CRAWebSiteMVC.Models.Employee'的实体失败,因为同一类型的另一个实体已经具有相同的主键值。这可能发生使用 'Attach' 方法或将实体的状态设置为 'Unchanged' 或 'Modified' 时,如果图中的任何实体具有冲突的键值。“此外,Original 目前没有用处。
  • 您删除了_entities.Employees.Add(objEmployee); 行吗?

标签: asp.net-mvc entity-framework-6


【解决方案1】:

您需要更新实体而不是重新插入它:

public Employee Edit(Employee objEmployee) // Work on EDIT
{

    _entities.Employees.Attach(objEmployee);   
    var entity = _entities.Entry(objEmployee);  
    entry.State = EntityState.Modified;      // Mark as modified

    _entities.SaveChanges();
    return objEmployee;
}

【讨论】:

  • var entity = Db.Entry(objEmployee);应该是var entry = _entity.Entry(objEmployee); 吗?
  • 遗憾的是,正如我告诉@StephenMuecke 我收到了同样的错误:Attaching an entity of type 'CRAWebSiteMVC.Models.Employee' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values 一旦我登陆Attach
  • 这通常是因为您的实体没有被正确跟踪并且已经分离。
  • 作为新技术的新手,我不知道跟踪是由什么组成的。我会调查一下,谢谢。
猜你喜欢
  • 2017-07-13
  • 2015-11-09
  • 2015-10-16
  • 1970-01-01
  • 1970-01-01
  • 2017-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多