每个 ID 删除许多记录 - MVC C#

Delete many records per ID - MVC C#

我的数据库设置是,Company 可以有很多 Engineer,也可以有很多 Territory。如果我应该从列表中删除一家公司,我需要彻底退出,而不是只从公司 table 中删除公司。我必须确保所有记录都被删除。所以没有 child/related 记录成为孤立数据。

如果我只想从所有 table 中删除一条记录,我会使用 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;

目前我没有级联删除设置,除此之外。任何其他选项。

一个选项可能是级联删除,您必须告诉 EF 为您执行此操作,因为默认情况下它不会执行此操作,应该执行类似这样的操作。还链接到其他几个 SO 答案,这些答案对一些额外的阅读有类似的吸引力。

modelBuilder.Entity<Company>()
        .HasMany(b => b.Engineer)
        .WillCascadeOnDelete(true);

为什么不使用.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

看看这个link。 它是一个扩展 EF 的库,并且(除其他外)提供批处理 update/delete 方法。

你的情况:

int companyid = 1;

context.Engineers.Delete(x=>x.CompanyId == companyid)
context.CompanyTerritories.Delete(x=>x.CompanyId == companyid)
context.Companies.Delete(x=>x.CompanyId == companyid)

如果您不介意使用 table 名称(最有效),请使用纯 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();       
    }
}

在 EF6 中,使用 RemoveRange 且不使用 foreach:

更容易
db.Engineers.RemoveRange(db.Engineers.Where(x => x.CompanyId == companyId));
db.SaveChanges();