简体   繁体   English

删除实体框架代码中的联结表记录(M:M)

[英]Delete junction table record in Entity Framework Code First (M:M)

How do I delete a record in a junction table within Entity Framework 5? 如何删除Entity Framework 5中联结表中的记录?

When reverse engineering my DataContext, Entity Framework seems to have recognized my junction table and automatically added Collections to my Models to represent the M:M relationship. 在对我的DataContext进行逆向工程时,实体框架似乎已经识别了我的联结表并自动将集合添加到我的模型中以表示M:M关系。 This is great when adding items, as I can simply build my entire Entity and everything gets inserted properly. 添加项目时这很棒,因为我可以简单地构建整个实体,并且所有内容都可以正确插入。 Perfect. 完善。

However, I'm stumped on removing a relationship. 但是,我很难消除关系。 For example, an Activity can have multiple Contacts associated to it, and this is linked using a junction table (dbo.ActivityContacts) that consists of the columns: 例如,一个Activity可以有多个与之关联的Contacts,并使用由列组成的联结表(dbo.ActivityContacts)进行链接:

  • ActivityID ActivityID
  • ContactID 使用ContactID

Both my Activity and Contact models have been updated by EF with Collections to represent the other. 我的活动和联系模型都已由EF和Collections更新,以代表另一个。 For example, my Activity model looks like this: 例如,我的Activity模型如下所示:

    public class Activity
    {
        public int ActivityID { get; set; }
        public string Subject { get; set; }
        public virtual ICollection<Contacts> Contacts { get; set; }
    }

In a non-EF environment, I would simply delete the record from the junction table and move on with my day. 在非EF环境中,我只是从联结表中删除记录,然后继续我的一天。 However, it seems I cannot access the junction table directly using EF, so I'm a tad confused on how to remove the record (relationship). 但是,似乎我无法使用EF直接访问联结表,所以我对如何删除记录(关系)感到困惑。

How can I properly remove a record from a junction table in Entity Framework? 如何从Entity Framework中的联结表中正确删除记录?

Entity Framework should remove the record for you, if you remove the associated object from either side of the relationship. 如果从关系的任一侧删除关联的对象,Entity Framework应该为您删除记录。

Assuming you've obtained this Activity instance from your context and want to remove a specific Contact with a known ID: 假设您已从上下文中获取此Activity实例,并希望删除具有已知ID的特定Contact

unwantedContact = context.Contacts.Find(contactID);
myActivity.Contacts.Remove(unwantedContact);

context.SaveChanges();

Should delete the record in your junction table, unless I'm being daft. 应该删除联结表中的记录,除非我是愚蠢的。

Agree with @Chris. 同意@Chris。

Another solution is to do: 另一种解决方案是:

context.Entry(activity).State = EntityState.Deleted;

ali golshani did a good job providing a solution. ali golshani做得很好,提供了解决方案。 Let me try to expand on it a little more. 让我尝试进一步扩展它。 In my scenario I have two list boxes where you can move items left or right (selected or not selected) 在我的场景中,我有两个列表框,您可以在其中向左或向右移动项目(选中或未选中)

The 'dto' object below is sent from the client. 下面的'dto'对象是从客户端发送的。 It's checking the selected state for each item in the list. 它正在检查列表中每个项目的选定状态。 If anyone knows of any way to improve this any more please leave feedback. 如果有人知道有任何改进方法,请留下反馈。

file_appender selectedAppender = context.file_appender.Find(dto.Id);

int[] ids = dto.Loggers.Where(x => !x.Selected).Select(x => x.Id).ToArray();
var loggers_to_delete = selectedAppender.logger.Where(x => ids.Contains(x.id));
loggers_to_delete.ToList().ForEach(x =>
{
    selectedAppender.logger.Remove(x);
});

ids = dto.Loggers.Where(x => x.Selected).Select(x => x.Id).ToArray();
var loggers_to_add = context.logger.Where(x => ids.Contains(x.id));
loggers_to_add.ToList().ForEach(x =>
{
    selectedAppender.logger.Add(x);
});

Lets look at another example....This one is for a list box with embedded check boxes (a little simpler). 让我们看另一个例子....这个是一个带有嵌入式复选框的列表框(更简单一点)。 Honestly this could probably be applied to the solution above to make easier to read code. 老实说,这可能适用于上面的解决方案,以便更容易阅读代码。

在此输入图像描述

protected void saveRelatedConnectors(test_engine testEngine, List<int> connectorTypes)
    var stepConnectorsToDelete = testEngine.step_connector.Where(x => (connectorTypes.Count == 0) || 
        (connectorTypes.Count != 0 && !connectorTypes.Contains(x.id)));
    stepConnectorsToDelete.ToList().ForEach(x =>
    {
        testEngine.step_connector.Remove(x);
    });

    var stepConnectorsToAdd = entities.step_connector.Where(x => connectorTypes.Contains(x.id));
    stepConnectorsToAdd.ToList().ForEach(x =>
    {
        testEngine.step_connector.Add(x);
    });

    entities.SaveChanges();
contact_to_delete = context.Contacts.Find(contactID);
selected_activity = context.Activity.Find(ActivityID);
context.Entry(selected_activity).Collection("Activity").Load();
selected_activity.Contacts.Remove(contact_to_delete);
db.SaveChanges(); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM