Reputation: 842
I have an entity Invoice
with 1 Provider
and many ParticularFieldValues
. In my invoice I have a unique index constraint in attribute InvoiceNumber.
The problem is that I want to do minimal changes in Invoice
, it throw an exception saying that I can't SaveChanges
because of duplicated unique index InvoiceNumber
.
I also tried with attach and it said that I cant because of the same duplicated.
Here is my table diagram:
Invoice class:
public class Invoice
{
public int InvoiceId { get; set; }
public int InvoiceNumber { get; set; }
public virtual int ProviderId { get; set; }
public virtual Provider Provider { get; set; }
public virtual ICollection<ParticularFieldValue> ParticularProviderFieldsToComplete { get; set; }
public DateTime DueDate { get; set; }
public int TotalAmount { get; set; }
}
Here is the operation I can't do:
public void UpdatePayment(Invoice inv)
{
UnitOfWork.Invoices.Update(inv);
UnitOfWork.Save();
}
public void Update(Invoice inv)
{
Invoice invDb = base.Get(inv.InvoiceId);
invDb.TotalAmount = inv.TotalAmount;
}
public TEntity Get(int id)
{
return dbSet.Find(id);
}
And the exception:
"ExceptionMessage": "An error occurred while updating the entries. See the inner exception for details.",
"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "No se puede insertar una fila de clave duplicada en el objeto 'dbo.Invoices' con índice único 'IX_InvoiceNumber'. El valor de la clave duplicada es (123451).\r\nSe terminó la instrucción.",
"ExceptionType": "System.Data.SqlClient.SqlException",
"StackTrace": "
en System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction)
1 wrapCloseInAction)
en System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action
en System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
en System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
en System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
en System.Data.SqlClient.SqlDataReader.get_MetaData()
en System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption)
en System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest) en System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
1 c) en System.Data.Entity.Infrastructure.Interception.InternalDispatcher
en System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
en System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
en System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
en System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
en System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<Reader>b__c(DbCommand t, DbCommandInterceptionContext1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func
3 operation, TInterceptionContext interceptionContext, Action3 executing, Action
3 executed)\r\n en System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)\r\n en System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)\r\n en System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)\r\n en System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.Execute(Dictionary2 identifierValues, List
1 generatedValues)\r\n en System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
Upvotes: 1
Views: 1352
Reputation: 1
Had the same issue, it turned out that before updating the entity, I first tried to add it, and if the record was already there, then under certain conditions I changed this record. And at the time of adding, when the error popped up that the record already exists, I forgot to call the Detach on this entity in time, so when I later tried to update my property, the first thing DbContext tried to do was add an entity that already exists in db (because of this, the error about the unique index was caused), but it never got to the point of updating. In short, check whether you have summoned Detach from entities everywhere.
Upvotes: 0