2012-04-18 51 views
0

我有一个出租属性的集合,每个出租属性都附有一组图像(作为子对象)。我正在使用一个sql ce数据库的EF 4.0,我需要能够从数据库中删除所有属性和图像。这里是我使用的代码:外键属性错误

private void SaveProperty() 
    { 
     try 
     { 
      if (PropertyList != null) 
      { 
       //Purge old database  
       IList<Property> ClearList = new List<Property>(from property in entities.Properties.Include("Images") select property); 
       foreach (Property a in ClearList) 
       { 
        if (a != null) 
        { 
         if (a.Images.Count != 0) 
         { 
          Property property = entities.Properties.FirstOrDefault(); 

          while (property.Images.Count > 0) 
          { 
           var image = property.Images.First(); 
           property.Images.Remove(image); 
           entities.DeleteObject(image); 
          } 

          entities.SaveChanges(); 
         } 
         entities.DeleteObject(a); 
         entities.SaveChanges(); 
        } 
       } 


       foreach(Property p in PropertyList.ToList()) 
       {       
        //Store sort (current position in list) 
        p.Sort = PropertyList.IndexOf(p); 
        entities.AddToProperties(p); 
        entities.SaveChanges(); 
       } 
      } 
     } 

     catch (Exception ex) 
     { 
      System.Windows.MessageBox.Show(ex.Message); 
     } 
    } 

我得到这个错误:操作失败:的关系无法改变,因为一个或多个外键的属性是不可为空。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新的关系,必须为外键属性指定另一个非空值,或者必须删除不相关的对象。

它直接在Image foreach循环后链接到SaveChanges()命令。任何想法,为什么我得到这个?

编辑:

这是旧代码,根据我的旧程序结构运行良好(无MVVM)。

 private void DeleteProperty() 
    { 
     if (buttonPres.IsChecked == false) 
     { 
      //Perform parts of DeleteImage() method to remove any references to images (ensures no FK errors) 
      Property p = this.DataContext as Property; 
      if (p == null) { return; } 

      MessageBoxResult result = System.Windows.MessageBox.Show(string.Format("Are you sure you want to delete property '{0}'?\nThis action cannot be undone.", p.SaleTitle), "Confirm Delete", MessageBoxButton.YesNo, MessageBoxImage.Question); 
      if (result == MessageBoxResult.Yes) 
       try 
       { 
        int max = listBoxImages.Items.Count; 
        for (int i = 0; i < max; i++) 
        { 
         Image img = (Image)listBoxImages.Items[0]; 
         entities.DeleteObject(img); 
         entities.SaveChanges(); 
        } 

        entities.DeleteObject(p); 
        entities.SaveChanges(); 
        BindData(); 
       } 
       catch (Exception ex) 
       { 
        System.Windows.MessageBox.Show(ex.Message, "Exception", MessageBoxButton.OK, MessageBoxImage.Error); 
       } 
     } 
    } 

注意:Binddata()只是刷新属性的列表框。

+0

可以吗在这里添加你的实体类的代码..? – 2012-04-18 09:28:26

+1

可能重复的[该关系无法更改,因为一个或多个外键属性是不可空的](http://stackoverflow.com/questions/5538974/the-relationship-could-not-be- change - 因为一个或多个这种外键的亲) – 2012-04-18 09:33:22

+0

它只是两个简单的实体类,一个用于属性和一个用于图像。一个属性可以有1 *多个图像。每个图像只有一个属性。要创建一个属性它只需要entities.property.add(新属性);对于图像我做CurrentProperty.Images.Add(新图像)。 – randomalbumtitle 2012-04-18 10:32:35

回答

0

我敢打赌删除图像后删除保存的变化,如果这种关系是一对多,你将更改保存到违反这种关系

尝试的状态:

 //Purge old database     
    foreach (Property a in entities.Properties) 
    { 
     if (a != null) 
     { 
      if (a.Images != null) 
      { 
       foreach (Image i in a.Images) 
       { 
        entities.Images.DeleteObject(i); 
       } 
      } 
      entities.Properties.DeleteObject(a); 
     } 

    } 
    entities.SaveChanges(); 
+0

图像属性可以设置为空,所以我不认为这是问题(即:关系是属性可以有很多图像或没有)。对不起,我以前没有说清楚。 – randomalbumtitle 2012-04-19 06:00:39

+0

你确定吗?那不是什么错误说 – 2012-04-19 07:15:21

+0

这是我的整个方法的代码。基本上我是从我的viewmodel与数据库进行通信,因为程序不够大而不能保证单独的数据层。该命令只是为了删除数据库中的所有现有数据,并使用observablecollection中的数据重新填充数据。当我将图像添加到属性并将其保存到数据库时,它会失败,但之后会删除该属性并保存更改。 – randomalbumtitle 2012-04-20 02:07:02