实体框架DELETE语句与REFERENCE约束冲突

use*_*973 12 entity-framework cascade foreign-keys

我对EF很新,我有一点问题.

我只想删除数据库中的项目.我正在使用SQL Server 2012 Express,VS2012,AdventureWorks 2012.

我执行的查询如下:

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

context.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

我得到的错误是

DELETE语句与REFERENCE约束"FK_SalesOrderHeader_Address_ShipToAddressID"冲突.冲突发生在数据库"AdventureWorks2012",表"Sales.SalesOrderHeader",列"ShipToAddressID"中.该语句已终止.

这实际上是删除项目和其他表中相应条目的好方法吗?

请指出我正确的方向.

   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; }
    }
Run Code Online (Sandbox Code Playgroud)

The*_*ads 17

无法从你所说的内容中说出多少,但是你可以从使用DbModelBuilder来解决级联问题中受益:

            modelBuilder.Entity<Parent>()
                .HasMany<Child>(c => c.Children)
                .WithOptional(x => x.Parent)
                .WillCascadeOnDelete(true);
Run Code Online (Sandbox Code Playgroud)

同样,需要有关模型结构的更多信息,以确定这是否是正确的方法.

无论是在您的删除方法中,还是首先删除所有子项,然后删除父项.


Hos*_*deh 6

  modelBuilder.Entity<Parent>()
  .HasMany<Child>(c => c.Children)
  .WithOptional(x => x.Parent)
  .WillCascadeOnDelete(true);
Run Code Online (Sandbox Code Playgroud)

或使用包含

  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);
Run Code Online (Sandbox Code Playgroud)

for .HasMany(...)。WithMany(...)包括就可以了

  • 实体框架应该正确设置您的模型构建器。我有一个类似的问题,只是包括添加的列表,为实体框架提供了管理外键删除的信息。 (2认同)

小智 6

您可以在 SQL 端解决此问题

方法一

  • 首先,您需要FK通过使用Replication monitor.

  • 右键单击它FK,单击Modify,您应该会看到如下所示的弹出框。

在此处输入图片说明

  • 从弹出框,选择Cascadedel

方法二

ON DELETE CASCADE在约束结束时在 sql 中设置。

  • 虽然这有效,但如果您在带有 CI 的项目中使用 Code-First,这不是一个真正可行的选择。您希望将其配置为自动以消除此类交互。在这种情况下,您可能希望在 OnModelCreated 期间使用 Fluent-API。 (2认同)