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

时间:2015-02-24 14:17:47

标签: c# asp.net-mvc entity-framework model-view-controller cascade

我拥有的数据库的设置是,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删除设置,所以除此之外。任何其他选择。

5 个答案:

答案 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);

https://stackoverflow.com/a/9241880/546411

https://stackoverflow.com/a/14493591/546411

答案 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();
}
相关问题