【问题标题】:How to seed data when using Model First approach?使用 Model First 方法时如何播种数据?
【发布时间】:2011-08-25 18:09:43
【问题描述】:

所以我正在学习 MVC3 和 EF4。 我尝试了代码优先方法,但它对我来说太混乱了。我可以毫无问题地创建类,但是当处理外键和彼此之间的关系时,困难的部分就来了。

但我先选择了模型。这样我可以直观地设计它并查看关系在哪里。

创建模型后,它会为我创建一个 SQL,我会针对我的 SQL Express 数据库执行该 SQL。完成了,完成了。

现在我想要表格中的数据。当然,我可以使用服务器资源管理器添加它们,但我很可能会在进行过程中对我的模型进行更改。并不断更新数据库。所以我不能一直手动输入数据。我知道如果您首先使用代码,您可以派生DropCreateDatabaseIfModelChanges 并覆盖seed 方法。

但是,如何使用模型优先方法做到这一点? 我有以下代码:

 public class DatabaseInitializer : IDatabaseInitializer<BettingContext> {
    public void InitializeDatabase(BettingContext context) {
        var teams = new List<Team> {
            new Team { Name="Toronto Maple Leafs", League="NHL"},
            new Team { Name="Boston Bruins", League="NHL"},
            new Team { Name="Vancouver Canucks", League="NHL"},
            new Team { Name="Nashville Predators", League="NHL"},
            new Team { Name="Montreal Canadiens", League="NHL"},
        };
    }
}

当然,在我的全局文件中:

protected void Application_Start()
{
    Database.SetInitializer<BettingContext>(new DatabaseInitializer());
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
}

那么现在呢?我如何告诉它运行该方法?我做错了什么?

【问题讨论】:

    标签: .net asp.net-mvc-3 entity-framework-4 seed ef-model-first


    【解决方案1】:

    我使用类似于以下的播种控制器:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using MyProject.Models;
    
    namespace MyProject.Controllers
    {
        public class SeedController : Controller
        {
            public string Index()
            {
                ContactDBContext db = new Models.ContactDBContext();
    
                Person person = new Person();
                person.FullName = "Mr Test";
                person.Notes = "It's me!";
                db.People.Add(person);
                db.SaveChanges();
                return "Seeding complete.";
            }
        }
    }
    

    然后,在您从模型实体图重新创建数据库后,只需导航到您网站的“/Seed”网址,它将重新填充您的种子数据。

    【讨论】:

      【解决方案2】:

      Model first 与 Code First 有很大不同,因为您实际上是在处理模型时从模型生成数据库。您获得 SQL 来创建数据库并手动运行它,因此我发现将第二个 SQL 脚本与我的种子数据放在旁边是合乎逻辑的。

      如果我对模型进行更改,SQL 脚本会更新,我当然需要查看我的种子 SQL 脚本(它位于我的数据库创建脚本旁边,很方便)我只是一个接一个地运行。

      到目前为止,这种方法运行良好,不会造成“此数据加载器在哪里以及它如何识别空数据库”的混淆。 (我还可以在我的安装项目中包含这两个 SQL 脚本,以便我的自定义操作使用种子数据创建数据库。)

      【讨论】:

        【解决方案3】:

        你可以有这样的东西:

        public class MySeedData : DropCreateDatabaseIfModelChanges<YourDataBaseContextClass>
        {
            protected override void Seed(YourDataBaseContextClass context)
            {  
               // Create objects here and add them to your context DBSets...
        
            }
        }
        
        public class YourDataBaseContextClass : DbContext
        {
        
        
        }
        

        然后,在Application_Start() 内调用:

        Database.SetInitializer(new MySeedData());
        

        在您的情况下,您可以尝试手动创建 DbSet(使用您的模型第一类)并尝试使用上面的代码插入它。它是模型优先 + 代码优先的混合体。

        public class FourthCoffeeWebContext : DbContext
        {
            public DbSet<Category> Categories { get; set; }
            public DbSet<Product> Products { get; set; }
        }
        

        添加到这里:CreateDatabaseIfNotExists<(Of <(<'TContext>)>)>

        【讨论】:

        • 即使我使用的是模型优先方法而不是代码优先方法,这是否可行?
        • 如何知道模型是否改变了?它没有元数据表。
        • @masfenix,有什么方法可以在模型优先上初始化数据库?你找到解决方案了吗?我尝试了上述方法,但没有启动数据库。
        猜你喜欢
        • 1970-01-01
        • 2012-01-16
        • 2011-09-12
        • 1970-01-01
        • 2016-01-31
        • 2018-10-09
        • 1970-01-01
        • 2012-06-07
        • 1970-01-01
        相关资源
        最近更新 更多