2017-04-02 72 views
0

在一個項目中我的工作,每當我清算項目名單後打電話SaveChanges(),我得到這個錯誤:entity.Items.Clear()在EF中做什麼?

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

我有這兩個類具有一對多的關係(最簡單的實現):

public class Company 
{ 
    public int Id {get; set;} 
    public string Name {get; set;} 
    public virtual List<Vehicle> Vehicles {get; set;} 
} 

public class Vehicle 
{ 
    public int Id {get; set;} 
    public string Model {get; set;} 

} 

我猜測,調用company.Vehicles.Clear()應該更新Vehicle表中的自動生成列Company_Id,將其值設置爲null,但似乎並不是上述錯誤的情況。 所以我想知道company.Vehicles.Clear()究竟在數據庫端做了什麼?

編輯

多虧了@McKabue的答案,他所提供的鏈接,我發現這是解決方案,這是完整的代碼:

var company = context.Set<GENCompany>(). 
         Include(m => m.Vehicles). 
         Include(m => m.Quotes). 
         Include(m => m.Phones). 
         Include(m => m.Persons). 
         Include(m => m.Leads). 
         Include(m => m.Emails). 
         Include(m => m.Drivers). 
         Include(m => m.Deals). 
         Include(m => m.Comments). 
         Include(m => m.Branches). 
         Include(m => m.Addresses). 
         SingleOrDefault(m => m.Id == companyModel.Id); 

        context.Entry(company).State = EntityState.Modified; 

        company.Vehicles.Clear(); 
        company.Drivers.Clear(); 
        company.Quotes.Clear(); 
        company.Persons.Clear(); 
        company.Leads.Clear(); 
        company.Deals.Clear(); 
        company.Branches.Clear(); 

        var phones = context.CompanyPhones.Where(x => x.CompanyId == companyModel.Id); 
        context.CompanyPhones.RemoveRange(phones); 

        var emails = context.CompanyEmails.Where(x => x.CompanyId == companyModel.Id); 
        context.CompanyEmails.RemoveRange(emails); 

        var comments = context.CompanyComments.Where(x => x.CompanyId == companyModel.Id); 
        context.CompanyComments.RemoveRange(comments); 

        var addresses = context.CompanyAddresses.Where(x => x.CompanyId == companyModel.Id); 
        context.CompanyAddresses.RemoveRange(addresses); 

對於一些實體,他們被刪除使用.Clear()語法,其他實體通過獲取其記錄並將其全部刪除(不僅是關係)而被刪除。這在目前的設計中非常有意義,例如在公司的創建頁面中,手機數據是手動添加的,而車輛是從下拉菜單中選擇的,同時它使這個完美的感覺,我覺得很困惑,以確定爲什麼發生這種情況,例如這裏是公司電話類:

public class GENCompanyPhone 
    { 
     [Key] 
     public long PhoneId { get; set; } 
     public long CompanyId { get; set; } 
     public long PhoneTypeId { get; set; } 
     public DateTime DateCreated { get; set; } = DateTime.Now; 
     public DateTime DateUpdated { get; set; } = DateTime.Now; 
     public Guid? CreatedById { get; set; } 
     public bool IsPublish { get; set; } = false; 
     public bool IsActive { get; set; } = false; 

     [MaxLength(255)] 
     [Index(IsUnique = true)] 
     public string PhoneNumber { get; set; } 
     [ForeignKey("CompanyId")] 
     public virtual GENCompany Company { get; set; } 
    } 

,另一方面,這是車輛類:

public class GENVehicle 
    { 
     public long Id { get; set; } 
     public long? BrandId { get; set; } 
     [ForeignKey("BrandId")] 
     public GENBrand Brand { get; set; } 
     public string Model { get; set; } 
     public DateTime? LicenseIssueDate { get; set; } 

     public Guid? CreatedById { get; set; } 

     [ForeignKey("VehicleTypeId")] 
     public virtual GENVehicleType VehicleType { get; set; } 
     public long? VehicleTypeId { get; set; }  
     public long? LicenseIssuerId { get; set; } 
     [ForeignKey("LicenseIssuerId")] 
     public GENEmployee LicenseIssuer { get; set; } 

    } 

我不能確定到底爲什麼EF與VehicleCompanyPhone

回答

1
交易不同

這意味着您正在清除在另一個表中引用的記錄。因此,EF警告你......有辦法可以避免這種通過設定Cascade delete

編輯 要刪除一個父表的子元素,實體需要的孩子被加載。

編輯2

var company = context.Set<GENCompany>().Where(m => m.Id == companyModel.Id); 
         Include(m => m.Vehicles). 
         Include(m => m.Quotes). 
         Include(m => m.Phones). 
         Include(m => m.Persons). 
         Include(m => m.Leads). 
         Include(m => m.Emails). 
         Include(m => m.Drivers). 
         Include(m => m.Deals). 
         Include(m => m.Comments). 
         Include(m => m.Branches). 
         Include(m => m.Addresses).SingleOrDefault(); 




        company.Vehicles.Clear(); 
        company.Drivers.Clear(); 
        company.Quotes.Clear(); 
        company.Persons.Clear(); 
        company.Leads.Clear(); 
        company.Deals.Clear(); 
        company.Branches.Clear(); 

,這將包括工作前

  1. 查詢
  2. 包括要刪除所有實體;
  3. 清除/ RemoveRange /由一個來自父刪除一個(目標公司)
+0

我不想刪除的記錄,我只是想撤銷通過設置外鍵關係爲null –

+0

這樣http://stackoverflow.com/a/15230641/3563013? – McKabue

+0

在這個答案中,他刪除了實體然後是子元素,我想刪除子元素並更新父代 –