我拥有的数据库的设置是,Company
可以包含多个Engineer
,并且可以包含多个Territory
。如果我应该从列表中删除公司,我需要做一个干净的退出,所以不要只删除公司表格中的公司表格。我必须确保所有记录都被删除。因此,没有子/相关记录成为孤儿数据。
如果我要从所有表中删除一条记录,我只需使用FirstOrDefault
删除它,然后我可以使用
public void RemoveCompany(long companyId)
{
using (var db = new BoilerServicingDbContext())
{
var ec = db.Engineers.FirstOrDefault(x => x.CompanyId == companyId);
db.Engineers.Remove(ec);
var tc = db.CompanyTerritories.FirstOrDefault(x => x.CompanyId == companyId);
db.CompanyTerritories.Remove(tc);
var p = db.Companies.FirstOrDefault(x => x.Id == companyId);
db.Companies.Remove(p);
db.SaveChanges();
}
}
但是,每家公司有不止一名工程师,每家公司有一个以上的领土。是否有一种简单的方法,如一般的数据库意义。
DELETE * FROM Engineers WHERE companyId = 1;
此刻我没有Cascading删除设置,所以除此之外。任何其他选择。
答案 0 :(得分:6)
为什么不使用.Where()
方法查找数据库中的所有相应项?像这样:
foreach(var ec in db.Engineers.Where(x => x.CompanyId == companyId))
{
db.Engineers.Remove(ec);
}
// same logic here for other tables
还要考虑@workabyte的答案,因为有一种方法可以在数据库中实现cascade delete
。
答案 1 :(得分:2)
一个选项可能是删除级联,你必须告诉EF为你这样做,因为它不会默认,这样的事情应该这样做。还与一些其他SO答案相关联,这些答案对于一些额外阅读具有相似的吸引力。
modelBuilder.Entity<Company>()
.HasMany(b => b.Engineer)
.WillCascadeOnDelete(true);
答案 2 :(得分:2)
如果您不介意使用表名(最有效),请使用纯SQL:
public void RemoveCompany(long companyId)
{
using (var db = new BoilerServicingDbContext())
{
var engineerIds = db.Engineers
.Where(x => x.CompanyId == companyId)
.Select(x => x.Id).ToList();
var sql = "DELETE FROM Engineers WHERE Id IN ({0})";
sql = string.Format(sql, string.Join(", ", engineerIds);
db.Database.ExecuteSqlCommand(sql);
db.SaveChanges();
}
}
答案 3 :(得分:0)
看看这个link。 它是一个扩展EF的库,以及(除其他外)提供批量更新/删除方法。
在你的情况下:
int companyid = 1;
context.Engineers.Delete(x=>x.CompanyId == companyid)
context.CompanyTerritories.Delete(x=>x.CompanyId == companyid)
context.Companies.Delete(x=>x.CompanyId == companyid)
答案 4 :(得分:0)
在EF6中使用 RemoveRange 并且没有foreach更容易:
public override TaskCompletionSource<object> CloseCompletionSource { get; set; }
public override void ViewDestroy()
{
if (CloseCompletionSource != null && !CloseCompletionSource.Task.IsCompleted && !CloseCompletionSource.Task.IsFaulted)
CloseCompletionSource?.TrySetCanceled();
base.ViewDestroy();
}