Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在实体框架核心中自动创建数据库_C#_Sqlite_.net Core_Entity Framework Core - Fatal编程技术网

C# 在实体框架核心中自动创建数据库

C# 在实体框架核心中自动创建数据库,c#,sqlite,.net-core,entity-framework-core,C#,Sqlite,.net Core,Entity Framework Core,我正在移植到.NET core的应用程序将使用带有SQLite的新EF core。我想在应用程序首次运行时自动创建数据库和表结构。根据EF核心文档,这是使用手动命令完成的 dotnet ef migrations add MyFirstMigration dotnet ef database update 但是,我不希望最终用户输入这些命令,而是希望应用程序创建并设置数据库以供首次使用。对于EF 6,有如下功能 Database.SetInitializer(new CreateDataba

我正在移植到.NET core的应用程序将使用带有SQLite的新EF core。我想在应用程序首次运行时自动创建数据库和表结构。根据EF核心文档,这是使用手动命令完成的

dotnet ef migrations add MyFirstMigration

dotnet ef database update
但是,我不希望最终用户输入这些命令,而是希望应用程序创建并设置数据库以供首次使用。对于EF 6,有如下功能

Database.SetInitializer(new CreateDatabaseIfNotExists<MyContext>());
Database.SetInitializer(新的CreateDatabaseIfNotExists());
但在EF Core中,这些似乎并不存在。我找不到任何与EF core等效的示例或文档,在EF core文档中缺少的功能列表中也没有提到。我已经设置了模型类,因此我可以编写一些代码来基于模型初始化数据库,但是如果框架自动执行此操作,则会更加容易。我不想自动构建模型或迁移,只是在新数据库上创建表结构


我是否在这里遗漏了什么,或者EF core中缺少了自动创建表功能?

如果您已经创建了迁移,您可以在Startup.cs中执行它们,如下所示

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
 {
      using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
      {
            var context = serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
            context.Database.Migrate();
      }
      
      ...
就在您调用重新创建()之前


改编自:

我的答案与里卡多的答案非常相似,但我觉得我的方法更简单一些,因为他的
函数中使用了大量的
,我甚至不确定它在较低级别上到底是如何工作的

因此,对于那些想要一个简单、干净的解决方案,为您创建一个数据库,让您确切地知道引擎盖下发生了什么的人,这是为您准备的:

public Startup(IHostingEnvironment env)
{
    using (var client = new TargetsContext())
    {
        client.Database.EnsureCreated();
    }
}

这几乎意味着在您创建的
DbContext
中(在本例中,我的名为
TargetsContext
),您可以使用
DbContext
的实例来确保在应用程序中运行Startup.cs时创建类中定义的表。

如果您尚未创建迁移,则有2个选项

1.从主应用程序创建数据库和表:

var context = services.GetRequiredService<YourRepository>();
context.Database.EnsureCreated();
var context=services.GetRequiredService();
context.Database.recreated();
2.如果数据库已存在,则创建表:

var context = services.GetRequiredService<YourRepository>();
context.Database.EnsureCreated();
RelationalDatabaseCreator databaseCreator =
(RelationalDatabaseCreator)context.Database.GetService<IDatabaseCreator>();
databaseCreator.CreateTables();
var context=services.GetRequiredService();
context.Database.recreated();
关系数据库创建者数据库创建者=
(RelationalDatabaseCreator)context.Database.GetService();
databaseCreator.CreateTables();

由于Bubi的

功能,如果您通过Startup.cs中的Configure参数列表获取上下文,则可以执行以下操作:

public void Configure(IApplicationBuilder app, IHostingEnvironment env,  LoggerFactory loggerFactory,
    ApplicationDbContext context)
 {
      context.Database.Migrate();
      ...

对于EF Core 2.0+我不得不采取不同的方法,因为他们更改了API。从2019年3月起,您将数据库迁移代码放在应用程序条目类中,但不在WebHost构建代码中

public class Program
{
    public static void Main(string[] args)
    {
        var host = CreateWebHostBuilder(args).Build();
        using (var serviceScope = host.Services.CreateScope())
        {
            var context = serviceScope.ServiceProvider.GetRequiredService<PersonContext>();
            context.Database.Migrate();
        }
        host.Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}
公共类程序
{
公共静态void Main(字符串[]args)
{
var host=CreateWebHostBuilder(args.Build();
使用(var serviceScope=host.Services.CreateScope())
{
var context=serviceScope.ServiceProvider.GetRequiredService();
Migrate();
}
host.Run();
}
公共静态IWebHostBuilder CreateWebHostBuilder(字符串[]args)=>
WebHost.CreateDefaultBuilder(args)
.UseStartup();
}

如果您希望重新创建和迁移这两个文件,请使用以下代码:

     using (var context = new YourDbContext())
            {
                if (context.Database.EnsureCreated())
                {
                    //auto migration when database created first time

                    //add migration history table

                    string createEFMigrationsHistoryCommand = $@"
USE [{context.Database.GetDbConnection().Database}];
SET ANSI_NULLS ON;
SET QUOTED_IDENTIFIER ON;
CREATE TABLE [dbo].[__EFMigrationsHistory](
    [MigrationId] [nvarchar](150) NOT NULL,
    [ProductVersion] [nvarchar](32) NOT NULL,
 CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY CLUSTERED 
(
    [MigrationId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY];
";
                    context.Database.ExecuteSqlRaw(createEFMigrationsHistoryCommand);

                    //insert all of migrations
                    var dbAssebmly = context.GetType().GetAssembly();
                    foreach (var item in dbAssebmly.GetTypes())
                    {
                        if (item.BaseType == typeof(Migration))
                        {
                            string migrationName = item.GetCustomAttributes<MigrationAttribute>().First().Id;
                            var version = typeof(Migration).Assembly.GetName().Version;
                            string efVersion = $"{version.Major}.{version.Minor}.{version.Build}";
                            context.Database.ExecuteSqlRaw("INSERT INTO __EFMigrationsHistory(MigrationId,ProductVersion) VALUES ({0},{1})", migrationName, efVersion);
                        }
                    }
                }
                context.Database.Migrate();
            }
使用(var context=new YourDbContext())
{
if(context.Database.recreated())
{
//首次创建数据库时自动迁移
//添加迁移历史记录表
字符串CreateEFMigrationHistoryCommand=$@”
使用[{context.Database.GetDbConnection().Database}];
将ANSI_空值设置为ON;
在上设置带引号的\u标识符;
创建表[dbo]。[UU EFMigrationsHistory](
[MigrationId][nvarchar](150)不为空,
[ProductVersion][nvarchar](32)不为空,
约束[PK__EFMigrationHistory]主键群集
(
[MigrationId]ASC
)在[主]上(PAD_INDEX=OFF,STATISTICS_norecocomputer=OFF,IGNORE_DUP_KEY=OFF,ALLOW_ROW_LOCKS=ON,ALLOW_PAGE_LOCKS=ON,OPTIMIZE_FOR_SEQUENTIAL_KEY=OFF)
)关于[初级];
";
context.Database.ExecuteSqlRaw(createEFMigrationsHistoryCommand);
//插入所有迁移
var dbAssebmly=context.GetType().GetAssembly();
foreach(dbAssebmly.GetTypes()中的var项)
{
if(item.BaseType==typeof(迁移))
{
字符串migrationName=item.GetCustomAttributes().First().Id;
var version=typeof(Migration.Assembly.GetName().version;
字符串efVersion=$“{version.Major}.{version.Minor}.{version.Build}”;
context.Database.ExecuteSqlRaw(“插入到uu efmigrationHistory(MigrationId,ProductVersion)值({0},{1})”,migrationName,efVersion);
}
}
}
Migrate();
}

我对EF还是个新手,我使用当前的数据库文件从VisualStudio创建了定义数据结构的类,首先使用EF 6代码“从数据库创建”。然后,我将它们剪切/粘贴到新的dotnet core VS解决方案中,所以我猜这些不是迁移。这是否意味着我必须先创建一个迁移文件,然后才能使用上述代码?很抱歉,我在回答中犯了一个错误,如果您不使用迁移,可以使用命令context.Database.EnsureCreated()/EnsureDeleted(),如果您需要这两种解决方案,详细信息将如何处理?我们刚刚将我们的应用程序移植到UWP并开始使用EF Core,这意味着一些用户需要从头开始创建DB,而另一些用户则需要创建DB
public class Program
{
    public static void Main(string[] args)
    {
        var host = CreateWebHostBuilder(args).Build();
        using (var serviceScope = host.Services.CreateScope())
        {
            var context = serviceScope.ServiceProvider.GetRequiredService<PersonContext>();
            context.Database.Migrate();
        }
        host.Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}
     using (var context = new YourDbContext())
            {
                if (context.Database.EnsureCreated())
                {
                    //auto migration when database created first time

                    //add migration history table

                    string createEFMigrationsHistoryCommand = $@"
USE [{context.Database.GetDbConnection().Database}];
SET ANSI_NULLS ON;
SET QUOTED_IDENTIFIER ON;
CREATE TABLE [dbo].[__EFMigrationsHistory](
    [MigrationId] [nvarchar](150) NOT NULL,
    [ProductVersion] [nvarchar](32) NOT NULL,
 CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY CLUSTERED 
(
    [MigrationId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY];
";
                    context.Database.ExecuteSqlRaw(createEFMigrationsHistoryCommand);

                    //insert all of migrations
                    var dbAssebmly = context.GetType().GetAssembly();
                    foreach (var item in dbAssebmly.GetTypes())
                    {
                        if (item.BaseType == typeof(Migration))
                        {
                            string migrationName = item.GetCustomAttributes<MigrationAttribute>().First().Id;
                            var version = typeof(Migration).Assembly.GetName().Version;
                            string efVersion = $"{version.Major}.{version.Minor}.{version.Build}";
                            context.Database.ExecuteSqlRaw("INSERT INTO __EFMigrationsHistory(MigrationId,ProductVersion) VALUES ({0},{1})", migrationName, efVersion);
                        }
                    }
                }
                context.Database.Migrate();
            }