【问题标题】:To delete a row from a table of only foreign keys using Entity Framework使用实体框架从只有外键的表中删除一行
【发布时间】:2018-06-12 17:04:48
【问题描述】:

我有一张桌子User { UserId, Name, Age }License { LicenseId, Name, IsActive }。我还有一张表UserLicense { UserId, LicenseId },它连接了这两个表,并记录了所有持有许可证的用户。一个用户可以持有多个许可证,这些许可证在UserLicense 表中显示为不同的行。

现在我需要从许可证表中删除一个特定的许可证。我不想直接删除它,所以我标记IsActive = false。但是,我确实想从 UserLicense 表中删除该许可证 ID 的行。

我正在使用实体框架。

如果是直接表,我会这样做:

var lic = db.Licenses.Where(l => l.Id== licenseId).FirstorDefault();
db.Licenses.Remove(lic);
db.SaveChanges();

但是由于UserLicense 是一个外键表,Entity Framework 不允许我直接使用它来访问它

public void DeleteLicensedUsers(Guid LicenseId)
{
    db.UserLicenses.Where()
}

因为模型不包含 UserLicense 的独立表,因为它只是一个外键表。

那么如何使用 Linq 和 EF6 删除特定 licenseIdUserLicense 表的所有行?

【问题讨论】:

标签: c# asp.net-mvc linq entity-framework-6


【解决方案1】:

如果您的实体类(我猜是User)具有ICollection<Licence> 类型的导航属性,通过从此集合中删除许可证,您实际上是从UserLicense 表中删除项目。这就是 Entity Framework 处理数据库中多对多关系的方式。

【讨论】:

    【解决方案2】:

    我遇到了类似的问题,您可以通过这种方式解决。我几乎倾向于避免使用只有外键的表,而是添加另一列来解决这个问题。

    var license = db.Licenses.Where(l => l.ID == LicenseId).FirstOrDefault();
    var users = license.Users.ToList();
    
    
    if (users != null)
    {
        foreach (var user in users)
        {
             license.Users.Remove(user);
        }                   
    }
    

    【讨论】:

      【解决方案3】:

      我对你的问题有点困惑。因此,如果您将许可证标记为isActive = false,并且仍然希望看到该许可证出现在用户页面上,那么UserLicense 表中应该仍然有一条记录将两者关联起来。

      也就是说,我相信来自类似问题的this answer 会对您有所帮助。

      本质上是这样的:

      //include licenses in the user entity
      var result = ctx.User.Include(x=>x.Licenses).Where(t=>t.Id == _id).FirstOrDefault()
      //get the licenses you are looking for, either equal or use .Contains
      var licensesOfUser = result.Where(x=>x.Licenses.Where(l=>l.id == _licenseId);
      //remove them from entity and save.
      result.Licenses.RemoveRange(licenseOfUser);
      ctx.SaveChanges();
      

      [编辑:如果你有执照]

      //include users in license entities  
      var result = ctx.License.Include(x=>x.Users).Where(t=>t.Id == _id).FirstOrDefault()
      //get the users you are looking for, either equal or use .Contains
      var usersOfLicenses = result.Where(x=>x.Users.Where(l=>l.id == _userId);
      //remove them from entity and save.
      result.Users.RemoveRange(licenseOfUser);
      ctx.SaveChanges();
      

      【讨论】:

      • 当我将许可证标记为 isActive = false 时,我不希望它出现在用户页面上。所以我确实想删除将两者关联的 UserLicense 表中的记录,但对用户或许可证表都不做任何事情。
      • 哦,好吧,我理解错了,说答案链接和代码示例将完全符合您的要求。
      • .Where(t=>t.Id == _id) 这部分不起作用,因为我没有用户 ID 但有许可证 ID。
      • 然后换一种方式,我将编辑我的答案edit:我已经编辑,所以现在您可以找到与许可证相关联的用户,而不是与您的相关联的许可证。
      • var usersOfLicenses = result.Where(x=>x.Users.Where(l=>l.id == _userId); 这行有问题。首先 results.where 不起作用在此上下文中没有 _userId。
      猜你喜欢
      • 2015-08-01
      • 2013-02-19
      • 1970-01-01
      • 2020-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-04
      相关资源
      最近更新 更多