【问题标题】:Entity Framework adding record into many to many mapping table实体框架将记录添加到多对多映射表中
【发布时间】:2016-02-06 12:32:45
【问题描述】:

我有 3 张桌子,

1) 客户(ID、姓名、bla bla)

2) 客户组(GroupId、GroupName)

3) CustomerInGroups (CustomerId, GroupId)

using (var context = DataObjectFactory.CreateContext())
{                
    context.Customers.Add(entity);
    context.SaveChanges();
    return entity.Id;
}

如何将记录添加到 CustomerInGroups? EntityFramework 不会为这种多对多映射表生成实体

编辑:

Customer 和 CustomerGroups 中的 Id 列都设置为自动递增。

所以在我的 CustomersGroup 表中,我有

Id          Name
----------------------------
1           Normal
2           VIP

我尝试按照其中一位海报的建议这样做:

entity.CustomerGroups = new List<CustomerGroup>
{
    new CustomerGroup {Id = 2 }
};
context.Customers.Add(entity);
context.SaveChanges();
return entity.Id;

但是,当我这样做时,不是像这样在映射表中创建记录:

CustomerId          GroupId
----------------------------
1                   2

我得到的是

CustomerInGroups
    CustomerId          GroupId
    ----------------------------
    1                   3

CustomerGroups
    Id          Name
    ----------------------------
    1           Normal
    2           VIP
    3           NULL

它实际上在我的 CustomerGroups 表中创建了另一个条目,这不是我想要的

【问题讨论】:

  • 当您将客户分配到组时,实体框架是否不会自动为您更新连接表,反之亦然?如果联接没有有效负载(即外键的联接),则无需创建单独的实体

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


【解决方案1】:

有点盲目,因为您没有包含 entity 的属性。但是您应该拥有与CustomerGroups 的关系的属性。只需将该属性设置为您要关联的组即可。例如,这将创建一个新的组名称“foo bar”并将实体与该组相关联。

using (var context = DataObjectFactory.CreateContext())
{
    entity.CustomerGroups = new List<CustomerGroup> { GroupName = "Foo bar" };
    context.Customers.Add(entity);
    context.SaveChanges();
    return entity.Id;
}

如果关系设置正确,EF 会自动在CustomerGroups 中插入一条记录,并在CustomerInGroups 表中插入一条关系。

编辑:

如果您尝试将现有 CustomerGroup 添加到新客户。您需要先从数据库中获取CustomerGroup,然后将其添加到您要插入的客户实体中。

using (var context = DataObjectFactory.CreateContext())
{
    var customerGroups = context.CustomerGroups.Where(...).ToList(); // get your CustomerGroup object(s) here, and ensure it's enumerated with ToList()
    entity.CustomerGroups = customerGroups;
    context.Customers.Add(entity);
    context.SaveChanges();
    return entity.Id;
}

【讨论】:

  • 这对我不起作用。它在我的组表中创建了另一条记录
  • @PapyrusBit 编辑了我的答案以允许已经创建 CustomerGroup。因此,您可以与来自客户的现有 CustomerGroup 相关联。
  • @StevenV 尽管我在第二个实体存在时遵循了你正在做的事情,但它仍在为我创造新记录:(
  • @Ciwan 您可能想发布一个新问题您的详细信息,并将此答案作为参考点。我认为社区会更好地为您服务。
【解决方案2】:

如果您尝试将 现有 客户分配给 _existing 组并假设 CustomerGroup 对象公开 ICollection,请执行以下操作:

(var context = DataObjectFactory.CreateContext())
{
    context.Customers.Add(entity);
    var group = context.CustomerGroups.Find(2); // or however you retrieve the existing group
    group.Customers.Add(entity);
    context.SaveChanges();
    return entity.Id
}

Find() 方法是 Entity Framework Code First (DbContext) 按 Id 查找的方法。我不记得“正确” ObjectContext 的做法,但是 .Single(g => g.Id == 2) 也可以。

理想情况下,您应该让我们更好地了解您的实体是如何映射的,以便我们知道您如何关联您的实体。

【讨论】:

  • 我正在做以上所有事情,但它仍在数据库中创建新记录!即使我告诉它使用现有记录并在新实体和新记录之间建立关系!
  • @Ciwan 你发布了一个新问题吗?仅根据您的评论很难回答。作为指导,请确保您没有将任何现有实体添加回任何 EF 上下文集合。
【解决方案3】:

除了@Steven-v 的回答,如果您之前获取了客户组并且您不想再次从数据库中获取它们,您也可以将它们附加到上下文中。

foreach (var c in customer.CustomerGroups)
{
     _db.CustomerGroups.Attach(c);
}        
_db.Customer.Add(customer);
_db.SaveChanges();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-17
    • 2018-01-01
    • 2013-06-30
    • 2014-08-21
    • 1970-01-01
    • 2017-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多