我对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();
我得到的错误是
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; }
}
答案 0 :(得分:17)
无法从你所说的内容中说出多少,但是你可以从使用DbModelBuilder解决级联问题中受益:
modelBuilder.Entity<Parent>()
.HasMany<Child>(c => c.Children)
.WithOptional(x => x.Parent)
.WillCascadeOnDelete(true);
同样,需要有关模型结构的更多信息,以确定这是否是正确的方法。
要么在删除方法中,要先删除所有子节点,然后删除父节点。
答案 1 :(得分:4)
modelBuilder.Entity<Parent>()
.HasMany<Child>(c => c.Children)
.WithOptional(x => x.Parent)
.WillCascadeOnDelete(true);
或使用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
答案 2 :(得分:3)
您可以在SQL端解决此问题
方法1 :
首先,您需要使用FK
找到已定义此Replication monitor
约束的表格。
右键点击FK
,点击Modify
,您会看到如下所示的弹出框。
Cascade
选择del
。方法2 :
在约束结束时在sql中设置ON DELETE CASCADE
。
答案 3 :(得分:0)
在EF Core中,构建器中的语法如下:
builder.HasOne(b => b.Parent )
.WithMany(a => a.Children)
.OnDelete(DeleteBehavior.Cascade);
https://docs.microsoft.com/en-us/ef/core/saving/cascade-delete
答案 4 :(得分:0)
创建实体B(引用实体A)然后尝试删除实体A时遇到此错误。SQL/ EF不允许我离开那个悬空的ID引用,因为objcet不再存在。级联删除可以解决此问题,但我希望B继续存在。所以我必须先删除B的引用,然后再删除A:
var existingContractApprovers = _repo.Query<ChangeOrderApproverForContract>().Where(coafc => coafc.ContractId == key).ToList();
//remove refs to contract approvers to preserve data integrity
foreach(var contractApp in existingContractApprovers)
{
var associatedChangeOrderApprovers = _repo.Query<ChangeOrderApprover>().AsNoTracking().Where(coafc => coafc.ChangeOrderApproverForContractId == contractApp.Id).ToList();
foreach(var coApp in associatedChangeOrderApprovers)
{
_repo.Edit(coApp);
coApp.ChangeOrderApproverForContractId = null;
}
}
_repo.SaveChanges();
//remove the contract approvers
foreach (var contractApp in existingContractApprovers)
{
_repo.Delete(contractApp);
}
_repo.SaveChanges();
答案 5 :(得分:0)
您可以在EF Core中执行此操作。
modelBuilder.Entity<Parent>()
.HasMany<Child>(c => c.Children)
.WithOne(s => s.Parent)
.OnDelete(DeleteBehavior.Cascade);
更安全的选择是确保在删除父级之前删除所有子级。仅当您完全了解实体之间的关系时,才应在Delete上级联。例如,您可能有很多订单连接到 您的电子商务商店中的某个类别。删除类别后,所有订单以及与该父类别相关联的外键都将消失。