我如何使用EF创建数据库并开始使用它?

问题描述 投票:0回答:1

我正在编写一个小应用程序,作为练习,以学习如何在C#.NET中使用SQL数据库。我的应用程序尝试打开与数据库的连接,如果连接失败,它将假定该数据库不在此处并创建该数据库。该数据库仅由我的应用使用,并且始终是本地的,因此它比许多其他数据库情况要简单得多。这是基于我在SO上以及在Andrew Proelsen撰写的“ Pro C#7:带有.NET和.NET Core”中阅读的内容的代码:

private static DbConnection connection = null;
private static MyAppModels context = null;
public static void SetupDatabase()
{
    string dataProvider = "System.Data.SqlClient";
    DbProviderFactory factory = DbProviderFactories.GetFactory(dataProvider);

    // get connection object (closes automatically at end of using scope)
    connection = factory.CreateConnection();
    if (connection == null) { /* throw Exception */ }

    string connectionString = @"Data Source=(localdb)\mssqllocaldb;Initial Catalog=MyAppDB;Integrated Security=True";
    connection.ConnectionString = connectionString;
    try { connection.Open(); }
    catch (Exception)
    {
        // database could not be found; try to create it...
        connection.ConnectionString = @"Data Source=(localdb)\mssqllocaldb;Integrated Security=True;database=master";
        connection.Open();
        string str = "CREATE DATABASE MyAppDB ON PRIMARY " +
                     "(NAME = MyApp_Data, FILENAME = 'C:\\Users\\Me\\Documents\\MyApp\\MyAppData.mdf', " +
                     "SIZE = 2MB, MAXSIZE = 50MB, FILEGROWTH = 10%) " +
                     "LOG ON (NAME = MyApp_Log, FILENAME = 'C:\\Users\\Me\\Documents\\MyApp\\MyAppLog.ldf', " +
                     "SIZE = 1MB, MAXSIZE = 10MB, FILEGROWTH = 10%)";
        DbCommand myCommand = connection.CreateCommand();
        myCommand.CommandText = str;
        try { myCommand.ExecuteNonQuery(); }
        catch (System.Exception ex) { /* throw Exception */ }
    }

    context = new MyAppModels(connection);
    return;
}

此代码似乎可以正常执行,直到我尝试将数据添加到表中时,出现以下错误:

“自创建数据库以来,支持'MyAppModels'上下文的模型已更改。请考虑使用代码优先迁移来更新数据库(http://go.microsoft.com/fwlink/?LinkId=238269)。”

如果退出我的应用程序并重新打开它,它可以连接到现有数据库并添加记录而不会出现问题。但是我不希望我的应用程序的用户在第一次安装后被要求退出并重新打开该应用程序,只是为了解决这个问题!

我在这里看过其他几篇文章,包括:

The model backing the 'POSContext' context has changed since the database was created

The model backing the context has changed since the database was created

这些似乎都指向相同的解决方案。另外,第二个引用了Microsoft EF团队成员的以下话:

首次创建模型时,我们运行DatabaseInitializer进行类似创建数据库(如果数据库不存在)或添加种子数据的操作。默认的DatabaseInitializer尝试将使用该模型所需的数据库架构与存储在使用数据库创建的EdmMetadata表中的架构的哈希进行比较(当Code First是创建数据库的架构时)。现有的数据库将没有EdmMetadata表,因此也将没有哈希表,如果缺少该表,今天的实现将被抛出。由于它是默认版本,因此在发布最终版本之前,我们将努力更改此行为。在此之前,现有数据库通常不需要任何数据库初始化程序,因此可以通过调用以下命令将其关闭以用于您的上下文类型:

Database.SetInitializer<YourDbContext>(null);

我不太了解这一切。但是我还是尝试将代码添加到我的DbContext类中:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    Database.SetInitializer<MyAppModels>(null);
    base.OnModelCreating(modelBuilder);
}

现在,当我尝试将第一条记录添加到表中时,出现以下错误:

“更新条目时发生错误。有关详细信息,请参见内部异常。”

内部例外:“字符串或二进制数据将被截断。该语句已终止。”

现在,如果我关闭并重新打开该应用程序,则每次都会发生相同的错误。所以现在情况变得更糟了。通过查看其他SO帖子,我看到此错误表示一个问题,即输入数据库的数据超出了字段大小。但是我在尝试添加的第一条记录上遇到了错误,并且绝对不会超出该表中的任何字段大小。

我怀疑我不应该将null传递给SetInitializer()。我注意到了以下注释:“ ...我们运行DatabaseInitializer进行诸如创建数据库(如果数据库不存在或添加种子数据)之类的操作。”我的代码已经在尝试处理数据库的创建。我的应用程序不应该这样做吗? SetInitializer()如何知道放置数据库或MAXSIZE的位置?而且我也不认为我需要它来“添加种子数据”。

[我也注意到了这一评论,“由于它是默认版本,因此我们将在交付最终版本(sic)之前努力更改此行为。”这听起来像个错误。该评论是在大约9年前写的,所以我希望它已经得到解决。

与此同时,有没有人对如何使其正常工作有任何提示?

我正在编写一个小应用程序,作为练习,以学习如何在C#.NET中使用SQL数据库。我的应用程序尝试打开与数据库的连接,如果失败,则假定该数据库为...

c# .net sql-server database entity-framework
1个回答
0
投票

© www.soinside.com 2019 - 2024. All rights reserved.