如何在种子期间将实体与实体框架相关联

时间:2015-07-02 18:28:22

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

我有这些课程:

[Serializable]
public class Module
{
        [Key]
        public int Id { get; set; }
        public string ModuleName { get; set; }
        public string FontAwesomeClass { get; set; }
}

[Serializable]
public class ModulosPorUsuario
{
        public string Email { get; set; }
        public List<Module> Modules{ get; set; }
}

我需要像这样播种:

#region Seed Modules
    context.Modulos.Add(new Module() { Id = 1, ModuleName = "Contabilidad", FontAwesomeClass = "fa-ambulance" });
    context.Modulos.Add(new Module() { Id = 2, ModuleName = "Recursos Humanos", FontAwesomeClass = "fa-heartbeat" });
    context.Modulos.Add(new Module() { Id = 3, ModuleName = "Inventario", FontAwesomeClass = "fa-anchor" });
    context.Modulos.Add(new Module() { Id = 3, ModuleName = "Produccion", FontAwesomeClass = "fa-binoculars" });
    context.Modulos.Add(new Module() { Id = 3, ModuleName = "Ventas", FontAwesomeClass = "fa-coffee" });
    context.Modulos.Add(new Module() { Id = 3, ModuleName = "Compras", FontAwesomeClass = "fa-calendar-o" });
    context.Modulos.Add(new Module() { Id = 3, ModuleName = "Cotizaciones", FontAwesomeClass = "fa-building" });
    #endregion

但是我的问题是如何关联之前播种的模块列表?

    #region Seed ModulosPor Usuario
    context.ModulosPorUsuario.Add(new ModulosPorUsuario()
    {
        Email = "companyadmin@xx.onmicrosoft.com",
        Modules = ???
    });

    #endregion

更新1:

当我检查为我创建的表时,这看起来并不合适。模块本身就是一个实体,而ModulesPeruser应该是电子邮件和许多不同模块之间的关系。 但是在Module表上,它为ModulesPerUser创建了一个外键。

我的设计出了什么问题? http://screencast.com/t/Z0u2950zm

4 个答案:

答案 0 :(得分:2)

var module1 = new Module() { Id = 1, ModuleName = "Contabilidad", FontAwesomeClass = "fa-ambulance" };
context.Modulos.Add(module);
context.ModulosPorUsuario.Add(new ModulosPorUsuario()
{
    Email = "companyadmin@xx.onmicrosoft.com",
    Modules = new List<Module>(){module1, module2 etc...};
});

答案 1 :(得分:0)

您可以保存模块列表,并在调用dbContext.SaveChanges()后将该集合分配给modulosPorUsuario对象并再次保存更改。

答案 2 :(得分:0)

termios

答案 3 :(得分:0)

要注意的事情:

  1. 每次更新数据库时都会运行种子。因此,您应该使用AddOrUpdate而不是Add来避免多次添加相同的项目。

  2. 使用AddOrUpdate时,只更新简单数据类型(字符串,整数等)。引用类实例或列表属性的属性将更新。

  3. 要绕过第二点,您应该更新id属性而不是引用属性。例如,给出以下内容:

    public class Foo
    {
        public int Id { get; set; }
    
        public string Name { get; set; }
    
        public int BarId { get; set; }
        public virtual Bar Bar { get; set; }
    }
    
    public class Bar
    {
        public int Id { get; set; }
    
        public string Name { get; set; }
    
        public virtual ICollection<Foo> Foos { get; set; }
    }
    

    您需要构建种子,如:

    var bar1 = new Bar { Name = "Bar 1" };
    var bar2 = new Bar { Name = "Bar 2" };
    var bar3 = new Bar { Name = "Bar 3" };
    
    context.Bars.AddOrUpdate(
        r => r.Name,
        bar1,
        bar2,
        bar3
     );
    
     context.SaveChanges();
    
     context.Foos.AddOrUpdate(
         r => r.Name,
         new Foo
         {
             Name = "Foo",
             BarId = bar1.Id
         }
      );
    

    这样,如果您想要更改Bar实例,Foo与之关联,您就可以。如果您使用Bar = bar1,则会在更新时忽略它。

    您的列表属性也是如此。在一对多的情况下,您应该像在上面的示例代码中那样在主体侧设置关系,而不是直接设置list属性,在此示例中为Bar.Foos

    在多对多中,您根本无法更新关系,因为双方都有一个集合,并且您无法访问连接表。您最初可以为关系设定种子,但在将来的种子中无法更新它们。