播种在 Entity Framework Code First 方法中不起作用

Seeding not working in Entity Framework Code First Approach

我正在开发一个 .Net 项目。我正在使用 entity framework 代码优先方法与数据库交互。我在开发过程中将一些模拟数据播种到我的数据库中。但是播种不起作用。我遵循了这个 link - http://www.entityframeworktutorial.net/code-first/seed-database-in-code-first.aspx.

这是我的 ContextInitializer class

public class ContextInitializer : System.Data.Entity.CreateDatabaseIfNotExists<StoreContext>
    {

        protected override void Seed(StoreContext context)
        {
            IList<Brand> brands = new List<Brand>();
            brands.Add(new Brand { Name = "Giordano" ,TotalSale = 1 });
            brands.Add(new Brand { Name = "Nike" , TotalSale = 3 });

            foreach(Brand brand in brands)
            {
                context.Brands.Add(brand);
            }
            base.Seed(context);
            context.SaveChanges();

        }
    }

这是我的上下文class

public class StoreContext : DbContext,IDisposable
    {
        public StoreContext():base("DefaultConnection")
        {
            Database.SetInitializer(new ContextInitializer());
        }

        public virtual DbSet<Category> Categories { get; set; }
        public virtual DbSet<Brand> Brands { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
        }
   }

这是我的品牌class

public class Brand
    {
        public int Id { get; set; }
        [Required]
        [MaxLength(40)]
        public string Name { get; set; }
        public int TotalSale { get; set; }
    }

我在网上搜索了解决方案并按照说明进行操作。我 运行 context.SaveChanges 也是。但它不是将数据播种到数据库。为什么它不起作用?

必须在之前设置数据库的初始值设定项,因此...

    public StoreContext():base("DefaultConnection")
    {
        Database.SetInitializer(new ContextInitializer());
    }

来晚了。如果你把它设为静态,那么它可以工作:

    static StoreContext()
    {
        Database.SetInitializer(new ContextInitializer());
    }

如果您删除现有数据库并且 EF 将创建数据并播种数据,您的代码将正常工作

您可以使用 DbMigrationsConfiguration 代替 CreateDatabaseIfNotExists 并按如下方式更改您的代码:

首先你必须删除现有的数据库

ContextInitializer class

public class ContextInitializer : System.Data.Entity.Migrations.DbMigrationsConfiguration<StoreContext>
{
    public ContextInitializer()
    {
        this.AutomaticMigrationDataLossAllowed = true;
        this.AutomaticMigrationsEnabled = true;
    }
    protected override void Seed(StoreContext context)
    {
        IList<Brand> brands = new List<Brand>();
        brands.Add(new Brand { Name = "Giordano", TotalSale = 1 });
        brands.Add(new Brand { Name = "Nike", TotalSale = 3 });

        foreach (Brand brand in brands)
        {
            context.Brands.AddOrUpdate(m => m.Name, brand);
        }
        base.Seed(context);
        context.SaveChanges();

    }
}

StoreContext

public class StoreContext : DbContext, IDisposable
    {
        public StoreContext() : base("DefaultConnection")
        {
            Database.SetInitializer(new MigrateDatabaseToLatestVersion<StoreContext, ContextInitializer>());
            //  Database.SetInitializer(new ContextInitializer());
        }

        public virtual DbSet<Category> Categories { get; set; }
        public virtual DbSet<Brand> Brands { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
        }
    }

然后您的种子中的任何更改都会自动反映到您的数据库中

您使用了错误的初始值设定项,仅当数据库不存在时才会调用 CreateDatabaseIfNotExists!

您可以使用例如 DropCreateDatabaseIfModelChanges:

解1)

public class ContextInitializer : System.Data.Entity.DropCreateDatabaseIfModelChanges<StoreContext>
{

你必须小心使用这种方法,它 !!!删除!!! 所有现有数据。

解决方案 2)

创建自定义 DbMigrationsConfiguration:

public class Configuration : DbMigrationsConfiguration<StoreContext>
{
    public Configuration()
    {
        // Take here! read about this property!
        this.AutomaticMigrationDataLossAllowed = true;
        this.AutomaticMigrationsEnabled = false;
    }

    protected override void Seed(StoreContext context)
    {
        IList<Brand> brands = new List<Brand>();
        brands.Add(new Brand { Name = "Giordano", TotalSale = 1 });
        brands.Add(new Brand { Name = "Nike", TotalSale = 3 });

        foreach (Brand brand in brands)
        {
            context.Brands.AddOrUpdate(m => m.Name, brand);
        }
        base.Seed(context);
        context.SaveChanges();
    }
}

通过这种方式你可以调用(!!在创建 DbContext 之前或在 DbContext 构造函数中!!):

// You can put me also in DbContext constuctor     
Database.SetInitializer(new MigrateDatabaseToLatestVersion<StoreContext , Yournamespace.Migrations.Configuration>("DefaultConnection"));

备注:

  • DbMigrationsConfiguration 需要了解连接字符串,您可以在构造函数中或从外部提供此信息。
  • 在您的 DbMigrationsConfiguration 中,您还可以配置:
    • 迁移命名空间
    • 迁移程序集
    • 迁移目录
    • 目标数据库

如果您像我的示例一样将所有内容都保留为默认值,那么您无需更改任何内容!