mardi 29 mars 2016

Exception when trying to SaveChanges with Entity Framework

I am building an MVVM WPF app in Visual Studio 2015 using Entity Framework 6. The app has a view with a few checkbox:

<TextBlock Grid.Row="0"
           Grid.Column="0"
           Style="{StaticResource FieldLabel}"
           Text="Inactive" />
<CheckBox Grid.Row="0"
          Grid.Column="1"
          IsChecked="{Binding IsSelectedEmployeeInActive,
                              Mode=TwoWay}" />
<TextBlock Grid.Row="1"
           Grid.Column="0"
           Style="{StaticResource FieldLabel}"
           Text="Leave of Absence" />
<CheckBox Grid.Row="1"
          Grid.Column="1"
          IsChecked="{Binding IsSelectedEmployeeLoa,
                              Mode=TwoWay}" />
<TextBlock Grid.Row="2"
           Grid.Column="0"
           Style="{StaticResource FieldLabel}"
           Text="Archived" />
<CheckBox Grid.Row="2"
          Grid.Column="1"
          IsChecked="{Binding IsSelectedEmployeeArchived,
                              Mode=TwoWay}" />

Each of these checkboxes is bound to a property, such as the following:

public bool IsSelectedEmployeeInActive
{
    get { return _isSelectedEmployeeInActive; }
    set
    {
        if (_isSelectedEmployeeInActive == value) return;

        _isSelectedEmployeeInActive = value;

        if (value)
        {
            var count = SelectedEmployee.EmployeeStatus.Count(x => x.validEmployeeStatusID.Equals(2));
            if (count.Equals(0))
            {
                SelectedEmployee.EmployeeStatus.Add(new EmployeeStatu
                {
                    employeeID = SelectedEmployee.employeeID,
                    validEmployeeStatusID = 2,
                    exitDate = DateTime.Now,
                    createdDate = DateTime.Now
                });
            }
        }
        else
        {
            var itemToRemove = SelectedEmployee.EmployeeStatus.Single(x => x.validEmployeeStatusID.Equals(2));
            Context.Entry(itemToRemove).State = EntityState.Deleted;
            SelectedEmployee.EmployeeStatus.Remove(itemToRemove);
        }
        RaisePropertyChanged(() => IsSelectedEmployeeInActive);
    }
}

The SelectedEmployee property gets set when the user clicks a row on a DataGrid. In the view model's constructor, the app has an event handler for changes to SelectedEmployee:

this.PropertyChanged += (o, e) =>
{
    if (e.PropertyName == nameof(this.SelectedEmployee))
    {
        IsSelectedEmployeeLoa = (SelectedEmployee.EmployeeStatus
                .Count(x => x.validEmployeeStatusID.Equals(2)) > 0);
        IsSelectedEmployeeArchived = (SelectedEmployee.EmployeeStatus
                .Count(x => x.validEmployeeStatusID.Equals(5)) > 0);
        IsSelectedEmployeeInActive = (SelectedEmployee.EmployeeStatus
                .Count(x => x.validEmployeeStatusID.Equals(4)) > 0);
    }
};

When the user clicks the Save button, it calls the following via a RelayCommand:

public void SaveEmployees()
{
    Context.SaveChanges();
}

If I change the CheckBox controls a few times between checked and unchecked and click Save, the app blows up with this exception on the Context.SaveChanges() line above:

{"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 http://ift.tt/1yZ9b1v for information on understanding and handling optimistic concurrency exceptions."}

If I comment out the code in the event handler for SelectedEmployee that sets the checkbox properties, the error goes away; but then I'm not able to set the CheckBox properties to their initial values from the database.

How should I resolve this issue? Thanks.




Aucun commentaire:

Enregistrer un commentaire