2015-01-27 4 views
0

Я получаю следующее сообщение об ошибке при попытке удалить элемент из БД:Ошибка при попытке каскадно-удалить

Операция не удалась: Отношения не могут быть изменены, потому что один или несколько из свойства внешнего ключа не имеют значения NULL. Когда происходит изменение отношения, соответствующее свойство внешнего ключа устанавливается равным нулевому значению. Если внешний ключ не поддерживает нулевые значения, необходимо определить новое отношение, для свойства внешнего ключа должно быть назначено другое ненулевое значение, или не связанный с ним объект должен быть удален.

Я читал много тем об этой проблеме, но ни один из них, похоже, не помогает (или, может быть, я их не очень хорошо понимаю).

мои модели:

public class ARDOperation 
    {  
     [Key]     
     public int ARD { get; set; } 

     [Required]    
     public virtual ICollection<Act> Actions { get; set; } 

     public ARDOperation() 
     { 
      this.Actions = new List<Act>(); 
     } 

    } 
public class Act 
{      
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int ARDID { get; set; } 
    public int ARDOperationId { get; set; } 

    [ForeignKey("ARDOperationId")]   
    public virtual ARDOperation ARDOperation { get; set; } 

    public string Data { get; set; } 

    [EnumDataType(typeof(ARDState))] 
    public ARDState State { get; set; } 
} 

Я также определил свободно API:

public class ARDOperationDBContext : DbContext 
    {    
     public DbSet<ARDOperation> ARDOperation { get; set; } 
     //public DbSet<Act> Act { get; set; } 

     protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      modelBuilder.Entity<Act>() 
      .HasRequired(t => t.ARDOperation) 
      .WithMany(t => t.Actions) 
      .HasForeignKey(d => d.ARDOperationId) 
      .WillCascadeOnDelete(true);     

      //modelBuilder.Entity<ARDOperation>() 

     } 

Метод в контроллере:

 internal void RemoveAction(int ARDID) 
     { 
     var op = ARDOperationDB.ARDOperation.Find(ARDID); 
     if (op != null) 
     { 
      //will not remove the "idle" action 
      if (op.Actions.Count > 1)         
      { 
       Act act = op.Actions.ElementAt(1);           
       op.Actions.Remove(act);      
       //ARDOperationDB.Entry(op).State = EntityState.Modified; 
       ARDOperationDB.SaveChanges();               
      }     
     } 
    } 

Я попытался определить «ARDOperationId «свойство как nullable (int?) с использованием подхода, основанного на кодах, и я не получаю никаких ошибок таким образом, но данные ребенка все еще остаются в БД.

Я думаю, что у меня отсутствует что-то, связанное с доступом к модели Act.

Поблагодарит за помощь, Yuval.

ответ

0

Так я прочитал кучу статей на эту тему. Ответ Криса здесь был действительно хорошим и полезным для моего понимания: Link

Но то, что действительно помогло мне, было примером небольшого кода здесь: Solution.

«[Key, ForeignKey (« Order »), Column (Order = 1)]« часть действительно сделала трюк.

Большое спасибо!

0

Посмотрите на [этот ответ] [1] от гуру EF о методе удаления.

EntityCollection.Remove (childEntity) отмечает взаимосвязь между родителем и childEntity как удаленные. Если сам childEntity является удалены из базы данных, и что именно происходит, когда вы звоните SaveChanges зависит от вида отношений между двумя:

Если отношения не является обязательным, то есть внешний ключ, который ссылается от ребенка к родительский элемент в базе данных допускает значения NULL, этот foreign будет установлен в null, и если вы вызываете SaveChanges, это значение NULL для childEntity будет записано в базу данных (т. е. связь между этими двумя удаленными). Это происходит с оператором UPDATE SQL . Операция DELETE не выполняется.

Если требуется соотношение (FK не допускает пустые значения) и отношения не идентификации (что означает, что внешний ключ не является частью ребенка (композитный) первичного ключа) вы должны либо добавьте ребенка другому родительскому элементу или вы должны явно удалить дочерний элемент (тогда с помощью DeleteObject). Если вы не сделаете ни одного из них, будет нарушено ссылочное ограничение , и EF будет генерировать исключение, когда вы вызываете SaveChanges - печально известный «Связь не может быть изменена, поскольку одно или несколько свойств внешнего ключа: non -неверное "исключение или подобное.

Если связь идентифицируется (обязательно требуется , потому что любая часть первичного ключа не может быть NULL) EF будет отмечать также дочерний статус как удаленный. Если вы вызываете SaveChanges, оператор SQL DELETE будет отправлен в базу данных. Если никакие другие ссылочные ограничений в базе данных не будут нарушены, объект будет удален, в противном случае будет выбрано исключение.

[1]: Entity Framework .Remove() vs. .DeleteObject()

+0

Спасибо за ваш ответ. Я уже знал об этом уже от исследования. Я попытался найти больше информации об использовании метода deleteObject, но не смог его получить. Во всяком случае, я нашел ответ. Большое спасибо за попытку. –

Смежные вопросы