Я вижу два «исправления»:
1) Вам не нужно заботиться о том, что внутри списка, так как вы собираетесь обновить список вариантов, вы можете начать с нуля, так что удаление часть становится
artist.ArtistTypes.Clear();
2) Теперь вы снова заполните этот список. ToList() не требуется, поскольку вы выполняете .Where(), чтобы получить данные, и вы можете использовать ленивые механизмы Linq, чтобы вы могли читать только данные, которые вы используете. Можно также разделить линии для повышения читаемости (это не имеет значения:. Пока не делать Еогеасп() БД не будет на самом деле удар
//note that the .ToList() is gone
var query = this._db.ArtistTypes.Where(artisttype => vm.SelectedIds.Contains(artisttype.ArtistTypeID);
foreach (var artistTtype in query))
{
artist.ArtistTypes.Add(artistTtype);
}
2b) (UNTESTED, с верхней части моей головы) Другой способ реализации сравнения вы делаете через пользовательский IEqualityComparer
, переключившись на метод .Intersect()
. Это более устойчиво, поскольку, если ваши ключи меняются в модели, вам нужно только изменить компаратор.
// I'm making up "ArtistType", fix according to your actual code
class ArtistTypeEqualityComparer : IEqualityComparer<ArtistType>
{
public bool Equals(ArtistType x, ArtistType y)
{
if (ArtistType.ReferenceEquals(x, null)) return false;
if (ArtistType.ReferenceEquals(y, null)) return false;
if (ArtistType.ReferenceEquals(x, y)) return true;
return x.ArtistTypeId.Equals(y.ArtistTypeId);
}
public int GetHashCode(ArtistType obj)
{
return obj.ArtistTypeId.GetHashCode();
}
}
// And then the "add" part simplifies
artist.ArtistTypes.AddRange(this._db.ArtistTypes.Intersect(vm.SelectedIds.Select(x => new ArtistType{ ArtistTypeId = x }));
Взгляните на это: [? Как я должен удалить все элементы в DbSet] (http://stackoverflow.com/questions/10448684/how-should-i-remove-all-elements-in -a-dbset). Может быть, проще выполнить SQL, чтобы удалить элементы коллекции 'ArtistType' (указав' ArtisId' в предложении 'where'). –