Я попробую объяснить просто мою модель Entity Framework. У меня есть объект User, у которого есть коллекция из нуля или более объектов UserInterest. Каждый объект интереса пользователя имеет только три свойства, уникальный идентификатор, идентификатор пользователя и описание.Не удается обновить объекты виртуального списка объектов Entity Framework
Всякий раз, когда пользователь обновляет объект User, он также должен обновлять связанные объекты UserInterest, но поскольку они являются бесплатной формой (то есть не являются частью списка разрешенных интересов), я хочу, чтобы пользователь передал список типов " строка "к веб-методу имен всех их интересов. В идеале код будет выглядеть в списке существующих пользователей, удалять все, что уже не актуально и добавлять новые, и оставить те, которые уже существуют.
Мои определения объектной модели
[Table("User")]
public class DbUser {
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public virtual IList<DbUserInterest> Interests { get; set; }
}
[Table("UserInterest")]
public class DbUserInterest : IEntityComparable<DbUserInterest>
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
public virtual DbUser User { get; set; }
public int? UserId { get; set; }
}
Контекст Fluent отображения
modelBuilder.Entity<DbUser>()
.HasKey(u => u.UserId);
modelBuilder.Entity<DbUser>()
.Property(u => u.UserId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<DbUser>()
.HasMany(u => u.Interests)
.WithRequired(p => p.User)
.WillCascadeOnDelete(true);
modelBuilder.Entity<DbUserInterest>()
.HasKey(p => p.Id);
modelBuilder.Entity<DbUserInterest>()
.Property(p => p.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<DbUserInterest>()
.HasRequired(p => p.User)
.WithMany(u => u.Interests)
.WillCascadeOnDelete(true);
И, наконец, мой WebMethod код и метод хранилища, чтобы сделать обновление
public UpdateUserProfileDetailsResponse UpdateUserProfileDetails(UpdateUserProfileDetailsRequest request)
{
try
{
var dbItem = _userDataRepository.GetItem(request.Header.UserId);
dbItem.Interests.Clear();
foreach (var dbInterest in request.UserInterests)
dbItem.Interests.Add(new DbUserInterest { Name = dbInterest, UserId = dbItem.UserId});
_userDataRepository.UpdateItem(dbItem);
_userDataRepository.Save();
}
catch (Exception ex)
{
}
}
public override bool UpdateItem(DbUser item)
{
var dbItem = GetItem(item.UserId);
if (dbItem == null)
throw new DataRepositoryException("User not found to update", "UserDataRepository.UpdateItem");
var dbInterests = Work.Context.UserInterests.Where(b => b.UserId == item.UserId).ToList();
var interestsToRemove = (from interest in dbInterests let found = item.Interests.Any(p => p.IsSame(interest)) where !found select interest).ToList();
var interestsToAdd = (from interest in item.Interests let found = dbInterests.Any(p => p.IsSame(interest)) where !found select interest).ToList();
foreach (var interest in interestsToRemove)
Work.Context.UserInterests.Remove(interest);
foreach (var interest in interestsToAdd)
{
interest.UserId = item.UserId;
Work.Context.UserInterests.Add(interest);
}
Work.Context.Entry(dbItem).State = EntityState.Modified;
return Work.Context.Entry(dbItem).GetValidationResult().IsValid;
}
Когда я запускаю это, на линии Repository.Save()
Я получаю исключение
Assert.IsTrue failed. An unexpected error occurred: An error occurred while updating the entries. See the inner exception for details.
Но интересно в WebMethod, если я закомментировать строку dbItem.Interests.Clear();
не выдаст ошибку, хотя тогда, конечно, вы получаете дубликаты или дополнительные элементы, как он думает, что все это новый интерес добавить. Однако удаление этой строки является единственным способом получить код, чтобы не ошибка
Раньше у меня было свойство UserId объекта Interest, которое было равно NULL, а затем ошибка была немного иной, что-то о вас не может изменить отношение внешнего ключа, который не имеет значения NULL, поэтому я изменил свойство на nullable, но все равно не пошел.
Любые мысли?
Что внутреннее исключение? – IronMan84
Это было нудно досадно – NZJames