title: Entity Framework 6: DbUpdateConcurrencyException
body: <p>I have function to create/update entity and "instead insert, update trigger". This error occurs when I'm creating new entity, but with updating it's OK and adding directly in database also works perfectly with this trigger.</p>
  
  <p>I'm using:</p>
  
  <ul>
  <li>.NET Framework 4.5</li>
  <li>Entity Framework 6.1.3</li>
  <li>MS SQL Server Express 2016</li>
  </ul>
  
  <blockquote>
    <p>Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. See <a href="http://go.microsoft.com/fwlink/?LinkId=472540" rel="nofollow noreferrer">http://go.microsoft.com/fwlink/?LinkId=472540</a> for information on understanding and handling optimistic concurrency exceptions.</p>
  </blockquote>
  
  <p>What I already tried:</p>
  
  <ol>
  <li><pre><code>catch (DbUpdateConcurrencyException ex)
  {
      var ctx = ((IObjectContextAdapter)db).ObjectContext;
      ctx.Refresh(RefreshMode.ClientWins, db.Plannings);
      db.SaveChanges();
      return new SaveResult(true);
  }
  </code></pre></li>
  <li><p>With and without SET NOCOUNT ON; </p></li>
  </ol>
  
  <p>Function:</p>
  
  <pre><code>public SaveResult Save(PlanningSaveModel model)
      {
          using (var db = new RTPContext())
          {
              try
              {
                  var entity = GetOrCreateEntity(db.Plannings, x =&gt; x.Id == model.Id).Item2;
                  int totalDays = (model.EndDate.Value - model.StartDate.Value).Days + 1;
                  if (totalDays &lt;= 0)
                  {
                      throw new Exception("Дата начала не может быть больше даты окончания");
                  }
                  entity.DocumentNumber = model.DocumentNumber;
                  entity.DocumentEndDate = model.DocumentEndDate.Value;
                  entity.UnitId = model.UnitId;
                  entity.UnitMarkId = model.UnitMarkId;
                  entity.Value = model.Value;
                  entity.MeasureUnitId = model.MeasureUnitId;
                  entity.StartDate = model.StartDate.Value;
                  entity.EndDate = model.EndDate.Value;
                  entity.CalendarWorkId = model.CalendarWorkId;
                  //entity.PerDayValue = (int)Math.Round(Decimal.Divide(model.Value, totalDays));
  
                  db.SaveChanges();
                  return new SaveResult(true);
              }
              catch (Exception ex)
              {
                  var errorMessage = ex.GetBaseException().Message;
                  return new SaveResult(false, errorMessage);
              }
          }
      }
  </code></pre>
  
  <p>Model:</p>
  
  <pre><code>public abstract class PlanningModel
  {
      [Key]
      public long? Id { get; set; }
      [Required]
      [Display(Name = "Document_Number", ResourceType = typeof(SharedStrings))]
      public string DocumentNumber { get; set; }
      [Required]
      [Display(Name = "Document_End_Date", ResourceType = typeof(SharedStrings))]
      public DateTime? DocumentEndDate { get; set; }
      [Required]
      [Display(Name = "Planning_Value", ResourceType = typeof(SharedStrings))]
      public int Value { get; set; }
      [Required]
      [Display(Name = "Date_Start", ResourceType = typeof(SharedStrings))]
      public DateTime? StartDate { get; set; }
      [Required]
      [Display(Name = "Date_End", ResourceType = typeof(SharedStrings))]
      public DateTime? EndDate { get; set; }
  }
  
  public class PlanningSaveModel : PlanningModel
  {
      [Required]
      [Display(Name = "Unit_Name", ResourceType = typeof(SharedStrings))]
      public long UnitId { get; set; }
      [Required]
      [Display(Name = "Unit_Mark_Name", ResourceType = typeof(SharedStrings))]
      public long UnitMarkId { get; set; }
      [Required]
      [Display(Name = "Measure_Unit_Name", ResourceType = typeof(SharedStrings))]
      public long MeasureUnitId { get; set; }
      [Required]
      [Display(Name = "Calendar_Work_Name", ResourceType = typeof(SharedStrings))]
      public long CalendarWorkId { get; set; }
  }
  </code></pre>
  
  <p>Trigger:</p>
  
  <pre><code>ALTER TRIGGER [dbo].[CalculatePerDayValue]
  ON  [dbo].[Planning]
  INSTEAD OF INSERT, UPDATE
  AS 
  BEGIN
  
  -- SET NOCOUNT ON added to prevent extra result sets from
  -- interfering with SELECT statements.
  SET NOCOUNT ON;
  
  IF EXISTS(SELECT * FROM deleted) BEGIN
      UPDATE dbo.Planning
      SET DocumentNumber = i.DocumentNumber,
          DocumentEndDate = i.DocumentEndDate,
          UnitId = i.UnitId,
          UnitMarkId = i.UnitMarkId,
          MeasureUnitId = i.MeasureUnitId,
          [Value] = i.[Value],
          StartDate = i.StartDate,
          EndDate = i.EndDate,
          CalendarWorkId = i.CalendarWorkId,
          PerDayValue = dbo.WorkDays(i.StartDate, i.EndDate, i.CalendarWorkId, i.Value),
          ModifierId = i.ModifierId,
          ModifyDate = i.ModifyDate,
          IsDeleted = i.IsDeleted,
          HVersion = i.HVersion
      FROM inserted i
      WHERE dbo.Planning.Id = i.Id
  END
  ELSE BEGIN
      INSERT INTO dbo.Planning
      SELECT [DocumentNumber]
         ,[DocumentEndDate]
         ,[UnitId]
         ,[UnitMarkId]
         ,[MeasureUnitId]
         ,[Value]
         ,[StartDate]
         ,[EndDate]
         ,[CalendarWorkId]
         ,dbo.WorkDays(StartDate, EndDate, CalendarWorkId, Value)
         ,[ModifierId]
         ,[ModifyDate]
         ,[IsDeleted]
         ,[HVersion] FROM inserted
  END
  END
  </code></pre>
  
  <p>Scalar function used in trigger:</p>
  
  <pre><code>ALTER FUNCTION [dbo].[WorkDays]
  (
      @Start datetime,
      @End datetime,
      @CalendarId bigint,
      @Value int
  )
  RETURNS int
  AS
  BEGIN
  -- Declare the return variable here
  DECLARE @WorkDays int
  
  -- Add the T-SQL statements to compute the return value here
  SELECT @WorkDays = CASE @CalendarId WHEN 1 
          THEN
          (DATEDIFF(dd, @Start, @End) + 1) - (DATEDIFF(wk, @Start, @End) * 2)
              - (case when DATEPART(dw, @Start) IN (6, 7) then 1 else 0 end)
              - (case when DATEPART(dw, @End) IN (6, 7) then 1 else 0 end)
              - (select count(*) from dbo.CalendarHoliday where [Date] between @Start and @End and DATEPART(dw, [Date]) NOT IN (6, 7))
          ELSE
          (DATEDIFF(dd, @Start, @End) + 1)
              - (select count(*) from dbo.CalendarHoliday where [Date] between @Start and @End)
          END
  
  -- Return the result of the function
  RETURN @Value/@WorkDays
  
  END
  </code></pre>