Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework DELETE statement conflicted with the REFERENCE constraint

I’m pretty new to EF and I have a little problem.

I just want to delete an item in my database. I’m using SQL Server 2012 Express, VS2012, AdventureWorks 2012.

The query that I execute is the following:

context = new AWEntities();
            var removedItem = context.Addresses
                .Include("StateProvince")
                .Include("SalesOrderHeaders")
                .Include("BusinessEntityAddresses").Single(d => d.AddressID == 11);
            context.Addresses.Remove(removedItem);

context.SaveChanges();

The error that I get is

The DELETE statement conflicted with the REFERENCE constraint "FK_SalesOrderHeader_Address_ShipToAddressID". The conflict occurred in database "AdventureWorks2012", table "Sales.SalesOrderHeader", column 'ShipToAddressID'. The statement has been terminated.

Is this actually a good way to delete items and the according entries in the other tables?

Please point me into the right direction.

   public partial class Address
    {
        public Address()
        {
            this.BusinessEntityAddresses = new HashSet<BusinessEntityAddress>();
            this.SalesOrderHeaders = new HashSet<SalesOrderHeader>();
        }

        public int AddressID { get; set; }
        public string AddressLine1 { get; set; }
        public string AddressLine2 { get; set; }
        public string City { get; set; }
        public int StateProvinceID { get; set; }
        public string PostalCode { get; set; }
        public System.Data.Spatial.DbGeography SpatialLocation { get; set; }
        public System.Guid rowguid { get; set; }
        public System.DateTime ModifiedDate { get; set; }

        public virtual StateProvince StateProvince { get; set; }
        public virtual ICollection<BusinessEntityAddress> BusinessEntityAddresses { get; set; }
        public virtual ICollection<SalesOrderHeader> SalesOrderHeaders { get; set; }
    }


public partial class StateProvince
    {
        public StateProvince()
        {
            this.Addresses = new HashSet<Address>();
            this.SalesTaxRates = new HashSet<SalesTaxRate>();
        }

        public int StateProvinceID { get; set; }
        public string StateProvinceCode { get; set; }
        public string CountryRegionCode { get; set; }
        public bool IsOnlyStateProvinceFlag { get; set; }
        public string Name { get; set; }
        public int TerritoryID { get; set; }
        public System.Guid rowguid { get; set; }
        public System.DateTime ModifiedDate { get; set; }

        public virtual ICollection<Address> Addresses { get; set; }
        public virtual CountryRegion CountryRegion { get; set; }
        public virtual ICollection<SalesTaxRate> SalesTaxRates { get; set; }
        public virtual SalesTerritory SalesTerritory { get; set; }
    }
}

public partial class BusinessEntityAddress
{
    public int BusinessEntityID { get; set; }
    public int AddressID { get; set; }
    public int AddressTypeID { get; set; }
    public System.Guid rowguid { get; set; }
    public System.DateTime ModifiedDate { get; set; }

    public virtual Address Address { get; set; }
    public virtual AddressType AddressType { get; set; }
    public virtual BusinessEntity BusinessEntity { get; set; }
}


public partial class SalesOrderHeader
    {
        public SalesOrderHeader()
        {
            this.SalesOrderDetails = new HashSet<SalesOrderDetail>();
            this.SalesOrderHeaderSalesReasons = new HashSet<SalesOrderHeaderSalesReason>();
        }

        public int SalesOrderID { get; set; }
        public byte RevisionNumber { get; set; }
        public System.DateTime OrderDate { get; set; }
        public System.DateTime DueDate { get; set; }
        public Nullable<System.DateTime> ShipDate { get; set; }
        public byte Status { get; set; }
        public bool OnlineOrderFlag { get; set; }
        public string SalesOrderNumber { get; set; }
        public string PurchaseOrderNumber { get; set; }
        public string AccountNumber { get; set; }
        public int CustomerID { get; set; }
        public Nullable<int> SalesPersonID { get; set; }
        public Nullable<int> TerritoryID { get; set; }
        public int BillToAddressID { get; set; }
        public int ShipToAddressID { get; set; }
        public int ShipMethodID { get; set; }
        public Nullable<int> CreditCardID { get; set; }
        public string CreditCardApprovalCode { get; set; }
        public Nullable<int> CurrencyRateID { get; set; }
        public decimal SubTotal { get; set; }
        public decimal TaxAmt { get; set; }
        public decimal Freight { get; set; }
        public decimal TotalDue { get; set; }
        public string Comment { get; set; }
        public System.Guid rowguid { get; set; }
        public System.DateTime ModifiedDate { get; set; }

        public virtual Address Address { get; set; }
        public virtual ShipMethod ShipMethod { get; set; }
        public virtual CreditCard CreditCard { get; set; }
        public virtual CurrencyRate CurrencyRate { get; set; }
        public virtual Customer Customer { get; set; }
        public virtual ICollection<SalesOrderDetail> SalesOrderDetails { get; set; }
        public virtual SalesPerson SalesPerson { get; set; }
        public virtual SalesTerritory SalesTerritory { get; set; }
        public virtual ICollection<SalesOrderHeaderSalesReason> SalesOrderHeaderSalesReasons { get; set; }
    }
like image 558
user2675973 Avatar asked Aug 13 '13 09:08

user2675973


3 Answers

Can't really tell much from what you have said, but you may benefit from looking into using the DbModelBuilder to solve cascade issues:

            modelBuilder.Entity<Parent>()
                .HasMany<Child>(c => c.Children)
                .WithOptional(x => x.Parent)
                .WillCascadeOnDelete(true);

Again, would need more information about your model structure to determine if this is the right approach.

Either that or in your delete method, remove any children first, and then remove the parent.

like image 110
Thewads Avatar answered Oct 14 '22 18:10

Thewads


  modelBuilder.Entity<Parent>()
  .HasMany<Child>(c => c.Children)
  .WithOptional(x => x.Parent)
  .WillCascadeOnDelete(true);

or use Include

  var adv = db.Adv.Include(b => b.Features)
                  .Include(b => b.AdvDetails)
                  .Include(b => b.AdvGallery)
                  .FirstOrDefault(b => b.Id == id);
  db.Adv.Remove(adv);

for .HasMany(...).WithMany(...) Include is ok

like image 20
Hossein Hajizadeh Avatar answered Oct 14 '22 20:10

Hossein Hajizadeh


You can resolve this issue on SQL side

Method 1 :

  • First, you need to find on which table this FK constraint has been defined, through using Replication monitor.

  • Right click on that FK, click Modify, you should get popup box like one shown below.

enter image description here

  • From the popup box, Select Cascade for del.

Method 2 :

set ON DELETE CASCADE in sql at the end of constraint.

like image 27
Muhammad Avatar answered Oct 14 '22 19:10

Muhammad