It might be that I don't understand exactly what happens, but it seems to me like you could simplify it a lot by removing all your outermost if statements and just performing the topmost codeblock.
private void UpdateUserDevices ( UserModel model )
{
// Get users current devices from database
var currentDevicesFromDatabase = _deviceRepository.FindByUserId( model.Id );
var devicesToAdd = model.Devices.Exclude( currentDevicesFromDatabase, d => d.Id ).ToList();
var devicesToDelete = currentDevicesFromDatabase.Exclude( model.Devices, d => d.Id ).ToList();
var workingDevices = model.Devices.Union( currentDevicesFromDatabase ).ToList();
foreach ( var device in workingDevices )
{
if ( devicesToAdd.Contains( device ) )
{
// Add devices
_deviceRepository.Create( device );
}
else if ( devicesToDelete.Contains( device ) )
{
// Delete devices
_deviceRepository.Delete( device );
}
else
{
// Update the rest
_deviceRepository.Update( device );
}
}
}
Actually the foreach could be split into three separate with no nested ifs.
private void UpdateUserDevices ( UserModel model )
{
var currentDevicesFromDatabase = _deviceRepository.FindByUserId( model.Id );
// Take the current model and remove all items from the database... This leaves us with only records that need to be added.
var devicesToAdd = model.Devices.Exclude( currentDevicesFromDatabase, d => d.Id ).ToList();
// Take the database and remove all items from the model... this leaves us with only records that need to be deleted
var devicesToDelete = currentDevicesFromDatabase.Exclude( model.Devices, d => d.Id ).ToList();
// Take the current model and remove all of the items that needed to be added... this leaves us with only updateable recoreds
var devicesToUpdate = model.Devices.Exclude(devicesToAdd, d => d.Id).ToList();
foreach ( var device in devicesToAdd )
_deviceRepository.Create( device );
foreach ( var device in devicesToDelete )
_deviceRepository.Delete( device );
foreach ( var device in devicesToUpdate )
_deviceRepository.Update( device );
}