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

时间:2013-07-09 01:17:27

标签: c# entity-framework many-to-many

如何删除Entity Framework 5中联结表中的记录?

对我的DataContext进行逆向工程时,Entity Framework似乎已经识别了我的联结表并自动将集合添加到我的模型中以表示M:M关系。添加项目时这很棒,因为我可以简单地构建整个实体,并且所有内容都可以正确插入。完美。

然而,我很难消除关系。例如,一个Activity可以有多个与之关联的Contacts,并使用由列组成的联结表(dbo.ActivityContacts)进行链接:

  • ActivityID
  • 的ContactID

我的活动和联系模型都已由EF和Collections更新,以代表另一个。例如,我的Activity模型如下所示:

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

在非EF环境中,我只是从联结表中删除记录,然后继续我的一天。但是,似乎我无法使用EF直接访问联结表,所以我对如何删除记录(关系)感到困惑。

如何从Entity Framework中的联结表中正确删除记录?

4 个答案:

答案 0 :(得分:2)

如果您从关系的任一侧删除关联的对象,则实体框架应该为您删除记录。

假设您已从上下文中获取此Activity个实例,并希望删除具有已知ID的特定Contact

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

context.SaveChanges();

应删除联结表中的记录,除非我愚蠢。

答案 1 :(得分:2)

同意@Chris。

另一种解决方案是:

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

答案 2 :(得分:1)

ali golshani提供了一个很好的解决方案。让我尝试进一步扩展它。在我的场景中,我有两个列表框,您可以在其中向左或向右移动项目(选中或未选中)

&#39; dto&#39;下面的对象是从客户端发送的。它会检查列表中每个项目的选定状态。如果有人知道有任何改进方法,请留下反馈意见。

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);
});

让我们看另一个例子....这个是一个带有嵌入式复选框的列表框(稍微简单一些)。老实说,这可能适用于上面的解决方案,以便更容易阅读代码。

enter image description here

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();

答案 3 :(得分:0)

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();