如何从ASP.NET MVC 5中的代码创建数据库?

时间:2016-01-31 18:15:17

标签: c# asp.net asp.net-mvc asp.net-mvc-5

我正在尝试学习ASP.NET MVC。我提前为我的基本问题道歉。

我在尝试使用模型类创建数据库时遇到问题。

这是我到目前为止所做的事情

我在"模型"下创建了一个模型类。像这样的文件夹

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;

namespace ScripterEngine.Models
{
    public class Campaign
    {
        public int id { get; set; }
        public string name { get; set; }
        public string layout { get; set; }
        public string call_list_connection { get; set; }
        public string call_list_table_name { get; set; }
        public string status { get; set; }
        public string intro_url { get; set; }
        public string use_transfer { get; set; }
        public string route_callback_to { get; set; }
        public string call_list_database_name { get; set; }
        public DateTime created_at { get; set; }
        public DateTime modified_at { get; set; }

        //Initilize the default value
        public Campaign()
        {
            status = "Active";
            use_transfer = "No";
            route_callback_to = "Self"; 
        }

    }
}

然后我在我创建的一个名为" DataAccessLayer"的新文件夹中创建了一个Campaign Context类。像这样

using ScripterEngine.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;

namespace ScripterEngine.DataAccessLayer
{
    public class CampaignContext : DbContext
    {
        public DbSet<Campaign> Campaign { get; set; }

        public CampaignContext() : base("con1")
        {

        }
    }
}

然后我在我创建的一个名为&#34; Seeders&#34;的新文件夹中创建了一个initilizer类。像这样添加虚拟数据

using ScripterEngine.Models;
using ScripterEngine.DataAccessLayer;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace ScripterEngine.Seeders
{
    public class CampaignSeeder : System.Data.Entity.DropCreateDatabaseIfModelChanges<CampaignContext>
    {

        protected override void Seed(CampaignContext context)
        {
            var campaigns = new List<Campaign>
            {
                new Campaign 
                {
                    id = 1,
                    name = "Ahold Landline",
                    layout = "topmenu",
                    call_list_table_name = "foo",
                    call_list_database_name = "bar",
                },
                new Campaign 
                {
                    id = 2,
                    name = "Ahold Cellphone",
                    layout = "topmenu",
                    call_list_table_name = "foo",
                    call_list_database_name = "bar",
                }
            };

            foreach (var campaign in campaigns)
            {
                context.Campaign.Add(campaign);
            }

            context.SaveChanges();

        }

    }
}

最后,我将连接字符串和一个contaxt块添加到我的Web.config

  //I want the database table to be in the App_Data folder
  <connectionStrings>
    <add name="con1" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=dbtest;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\dbtest.mdf" providerName="System.Data.SqlClient"/>
  </connectionStrings>

和conext块

   <contexts>
      <context type="ScripterEngine.DataAccessLayer.CampaignContext" disableDatabaseInitialization="false">
        <databaseInitializer type="ScripterEngine.Seeders.CampaignSeeder" />
      </context>
    </contexts>

但表格没有创建?我是否需要触发表格生成的内容?对于不创建的表,我做错了什么?

此外,我正在尝试了解组织应用程序的正确方法。为每个模型设置一个单独的上下文类是否正确,或者每个模型都应该有一个上下文类?换句话说,上下文类应该表示表还是数据库本身?

谢谢

2 个答案:

答案 0 :(得分:4)

您可以使用包管理控制台执行以下命令:

enable-migrations

add-migration Initial

update-database

这将启用代码优先方法的迁移。然后创建db脚本以基于dbcontext设置数据库。然后根据之前创建的迁移脚本更新数据库(并运行种子)。

Link showing in more detail

答案 1 :(得分:0)

是的,一旦您访问它,就会创建数据库。因此,只需打开MVC项目的起始页面就不会创建任何内容(除非你在那里放置访问数据库的东西)。

回答您的问题,您的CampaignContext或任何继承DbContext的类都代表一个数据库。对于每个模型,您可以创建一个DbSet,就像您对Campaign所做的那样,这表明每个Model代表数据库中的一个表,但请记住,这不是一个严格的规则,具体取决于您使用的体系结构。

要在没有包管理器控制台的情况下生成表,您可以按照以下说明操作。我喜欢在开发过程中这样做,因为有时候我喜欢强制我的数据库再次使用新数据重新创建,但这取决于每个开发人员。我喜欢使用控制台来安装软件包,更新它们,以及在我不想删除它时更新数据库,因为你的方式,如果你改变模型,你的数据库将被删除并重新创建,这意味着你将丢失任何那里的数据,虽然你的种子方法会再次运行。

此外,如果您正在开发客户端并且无法连接到客户端的数据库(尽管在常见情况下您可以执行此操作),这非常有用,那么您可以按照CreateDatabaseIfNotExists方法。

您可以将其放在Global.asmxStartup.cs

 protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        CampaignContext context = new CampaignContext();
        context.Database.Initialize(false);
    }

请记住,您的上下文不会在这里创建,这只是一个例子。如果您不想等到通过另一个页面访问数据库,则只需要这样做。

另外,由于我不想在web.config中保存内容,因此我更改了CampaignContext的构造函数:

    public CampaignContext()
        : base("con1")
    {
        Database.SetInitializer<CampaignContext>(new CampaignSeeder());
    }

因此,您可以从web.config中删除它:

   <contexts>
      <context type="ScripterEngine.DataAccessLayer.CampaignContext" disableDatabaseInitialization="false">
        <databaseInitializer type="ScripterEngine.Seeders.CampaignSeeder" />
      </context>
    </contexts>

然后在App的根目录中添加迁移文件夹,并添加名为Configuration.cs的文件:

internal sealed class Configuration : DbMigrationsConfiguration<ScripterEngine.DataAccessLayer.CampaignContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
    }

}

然后运行您的应用程序。在Seed()方法中放置一个断点。