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

C# 如何从ASP.NET MVC 5中的代码创建数据库?,c#,asp.net,asp.net-mvc,asp.net-mvc-5,C#,Asp.net,Asp.net Mvc,Asp.net Mvc 5,我正在努力学习ASP.NETMVC。我为我的基本问题提前道歉 我在尝试使用模型类创建数据库时遇到问题 以下是我迄今为止所做的工作 我在“Models”文件夹下创建了一个模型类,如下所示 using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Web; namespace ScripterEngine.Models { public

我正在努力学习ASP.NETMVC。我为我的基本问题提前道歉

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

以下是我迄今为止所做的工作

我在“Models”文件夹下创建了一个模型类,如下所示

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"; 
        }

    }
}
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")
        {

        }
    }
}
然后,我在一个名为“DataAccessLayer”的新文件夹中创建了一个活动上下文类,如下所示

使用ScripterEngine.Models;
使用制度;
使用System.Collections.Generic;
使用System.Data.Entity;
使用System.Linq;
使用System.Web;
命名空间ScripterEngine.DataAccessLayer
{
公共类活动上下文:DbContext
{
公共数据库集活动{get;set;}
公共活动上下文():基础(“con1”)
{
}
}
}
然后,我在一个名为“Seeders”的新文件夹中创建了一个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();

        }

    }
}
使用ScripterEngine.Models;
使用ScripterEngine.DataAccessLayer;
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
命名空间ScripterEngine.Seeders
{
公共类活动种子程序:System.Data.Entity.DropCreateDatabaseIfModelChanges
{
受保护的覆盖无效种子(活动上下文)
{
var活动=新列表
{
新战役
{
id=1,
name=“Ahold固定电话”,
layout=“topmenu”,
调用\u list\u table\u name=“foo”,
调用\u列表\u数据库\u name=“bar”,
},
新战役
{
id=2,
name=“Ahold手机”,
layout=“topmenu”,
调用\u list\u table\u name=“foo”,
调用\u列表\u数据库\u name=“bar”,
}
};
foreach(活动中的var活动)
{
context.Campaign.Add(活动);
}
SaveChanges();
}
}
}
最后,我在Web.config中添加了连接字符串和contaxt块

  //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>
//我希望数据库表位于App\u Data文件夹中
和conext块

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

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

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


谢谢

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

enable-migrations

add-migration Initial

update-database
这将支持代码优先方法的迁移。然后创建db脚本,以根据dbcontext设置db。然后根据前面创建的迁移脚本更新数据库(并运行种子)


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

enable-migrations

add-migration Initial

update-database
这将支持代码优先方法的迁移。然后创建db脚本,以根据dbcontext设置db。然后根据前面创建的迁移脚本更新数据库(并运行种子)


是的,一旦您访问数据库,就会创建该数据库。所以,仅仅打开MVC项目的起始页根本不会创建任何内容(除非您在那里放置了访问数据库的内容)

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

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

此外,如果您正在开发一个客户机,而您无法连接到客户机的数据库(虽然在常见情况下您可以这样做),那么这非常有用,您可以采用CreateDatabaseIfNotExists方法

您可以将其放入
Global.asmx
Startup.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中,因此我更改了您的活动上下文的构造函数:

    public CampaignContext()
        : base("con1")
    {
        Database.SetInitializer<CampaignContext>(new CampaignSeeder());
    }
公共活动上下文()
:base(“con1”)
{
SetInitializer(new activationseeder());
}
因此,您可以从web.config中删除此选项:

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

然后在应用程序的根目录中添加一个迁移文件夹,并添加一个名为Configuration.cs的文件:

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

}
内部密封类配置:dbmigtorinsconfiguration
{
公共配置()
{
AutomaticMiggerationsEnabled=真;
}
}

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

是的,一旦访问数据库,就会创建该数据库。所以,仅仅打开MVC项目的起始页根本不会创建任何内容(除非您在那里放置了访问数据库的内容)

回答您的问题时,您的活动上下文或任何继承DbContext的类都表示一个数据库。对于每个模型,您都可以创建一个DbSet,比如