Я использую GraphDiff для обновления графов отдельных объектов и получаю указанное выше исключение при сохранении родителя и его дети.
Модели и отображение:
public class Group
{
public int Id { get; set; }
public virtual ICollection<GroupUser> Users{ get; set; }
}
public class GroupUser
{
public int Id { get; set; }
public int GroupId { get; set; }
public int UserId { get; set; }
public virtual User User { get; set; }
}
public class GroupMap : EntityTypeConfiguration<Group>
{
public GroupMap()
{
this.ToTable("groups");
this.HasKey(t => t.Id).Property(t => t.Id).HasColumnName("id").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.HasMany(t => t.Users)
.WithOptional()
.HasForeignKey(d => d.GroupId)
.WillCascadeOnDelete();
}
}
public class GroupUserMap : EntityTypeConfiguration<GroupUser>
{
public GroupUserMap ()
{
this.ToTable("groups_users");
this.HasKey(t => t.Id).Property(t => t.Id).HasColumnName("id").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.Property(t => t.GroupId).HasColumnName("group_id").IsRequired();
this.Property(t => t.UserId).HasColumnName("user_id").IsRequired();
this.HasRequired(t => t.User)
.WithMany()
.HasForeignKey(d => d.UserId)
.WillCascadeOnDelete(false);
}
}
Для вставок и обновлений у меня есть следующий метод в моем репозитории:
public override Group Update(Group entity)
{
if (entity.Users != null)
{
entity.Users.ToList()
.ForEach(x =>
{
x.GroupId = x.Id == 0 ? 0 : entity.Id;
x.UserId = x.User.Id;
});
}
return dbContext.UpdateGraph<Group>
(entity,
map => map.OwnedCollection(x => x.Users, with => with.AssociatedEntity(c => c.Users))
);
}
Я делаю следующее:
- Добавьте новую группу, сохраните и перезагрузите
- Добавьте пользователя в группу, сохраните и перезагрузите
- Добавьте второго пользователя, сохраните и перезагрузите
- Добавьте третьего пользователя, попробуйте сохранить -> выдается исключение
Во время отладки состояние добавляемых пользовательских объектов всегда отсоединено, а GroupId
и Id
устанавливаются на 0 для новых объектов. Первые 2 добавленных пользователя успешно сохранены. Однако на третьем выбрасывается исключение.
Если я всегда использую один и тот же метод сохранения, почему он не всегда работает? Это проблема EF
или GraphDiff
и есть ли способ решить эту проблему?
Большинство вопросов и связанных ответов здесь, в SO и в других местах, касаются ситуации, когда дочерний объект удаляется. В моем конкретном случае это не так.