2017-04-02 73 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

在这个答案中,他删除了实体然后是子元素,我想删除子元素并更新父代 –