C# 如何使用EF创建数据库并开始使用它?
我正在编写一个小应用程序作为练习,学习如何在C#NET中使用SQL数据库。我的应用程序尝试打开与数据库的连接,如果连接失败,它会假定数据库不在那里并创建它。此数据库仅由我的应用程序使用,并且始终是本地的,因此它比许多其他数据库情况简单得多。以下是代码,基于我之前读过的内容,以及Andrew Troelsen在“Pro C#7:With.NET and.NET Core”中的内容:C# 如何使用EF创建数据库并开始使用它?,c#,.net,sql-server,database,entity-framework,C#,.net,Sql Server,Database,Entity Framework,我正在编写一个小应用程序作为练习,学习如何在C#NET中使用SQL数据库。我的应用程序尝试打开与数据库的连接,如果连接失败,它会假定数据库不在那里并创建它。此数据库仅由我的应用程序使用,并且始终是本地的,因此它比许多其他数据库情况简单得多。以下是代码,基于我之前读过的内容,以及Andrew Troelsen在“Pro C#7:With.NET and.NET Core”中的内容: private static DbConnection connection = null; private sta
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;
}
在我尝试将数据添加到表中之前,此代码的执行似乎没有任何问题,此时出现以下错误:
“自创建数据库以来,支持MyAppMode上下文的模型发生了变化。请考虑使用代码第一次迁移来更新数据库()。”
如果我退出应用程序并重新打开它,它就能够连接到现有的数据库并添加记录,而不会出现问题。但我不希望我的应用程序的用户在第一次安装应用程序后被要求退出并重新打开应用程序,只是为了避开这个问题
我在这里查看了其他几个帖子,包括:
这两者似乎指向同一个解决方案。另外,第二个引用了Microsoft EF团队成员的以下话:
第一次创建模型时,我们运行DatabaseInitializer来执行创建数据库(如果数据库不存在)或添加种子数据等操作。默认DatabaseInitializer尝试将使用模型所需的数据库架构与使用数据库创建的EdmMetadata表中存储的架构哈希进行比较(当Code First是创建数据库的代码时)。现有数据库不会有EdmMetadata表,因此也不会有哈希……如果缺少该表,今天的实现将抛出。在发布最终版本之前,我们将致力于更改此行为,因为它是默认版本。在此之前,现有数据库通常不需要任何数据库初始值设定项,因此可以通过调用以下命令来关闭上下文类型的初始值设定项:
看起来应该没有必要,但它是有效的
然后我尝试了别的东西。我用一行代码替换了SetupDatabase()中的所有代码,正如我在几个示例教程中看到的:
context = new MyAppModels();
这允许/依赖EF打开数据库,如有必要(在某些未定义/默认位置)创建数据库。当数据库已经存在时,该操作有效,但当需要创建数据库时,该操作失败:
System.Data.SqlClient.SqlException HResult=0x80131904消息=创建文件遇到操作系统错误5(访问被拒绝。) 试图打开或创建物理文件时 “C:\Users\MyAppDB.mdf”。创建数据库失败。一些文件 无法创建列出的名称。检查相关错误。Source=.Net SqlClient数据提供程序 请注意,和MyAppDB.mdf之间缺少反斜杠。我不知道为什么会发生这种情况,也不知道如何解决。我在App.config中看不到任何明显的东西可以控制这个
<connectionStrings>
<add name="MyAppConnection" connectionString="data source=(localdb)\mssqllocaldb;initial catalog=MyAppDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
</connectionStrings>
有人能帮我解决这个问题吗,这样我就可以使用“纯”EF,还是我需要回到我的黑客程序中去…?好的
是代码,基于我读过的东西,也是在“Pro C#7:With.NET和.NET Core”中读到的
您似乎已经尝试过混合手动创建数据库和创建数据库 结果很糟糕 我们能解决这个问题吗 是的……有一些额外的细节/代码,甚至可能需要从头开始重新编写很多东西,所以我不确定这是否值得花时间,因为您似乎在研究技术,而不是试图解决一些关键业务内部程序套件中的技术问题 因此,我建议您决定要学习什么,并使用标准教程逐步学习:
context = new MyAppModels();
注意:您似乎正在使用EF6(正如您所使用的),但我建议您开始学习,因为它是Entity Framework的最新迭代。您发布的代码是如何使用“动态”SQL“手动”创建数据库。在使用实体框架时,根本不需要使用这种方法 从实体框架开始,最简单的方法之一是首先使用模型:
- 将新的“ADO.NET实体数据模型”添加到项目中
- 选择“空EF设计器模型”
- 编辑模型以设计数据库
- 保存后(或在VS2019中,您必须在.tt文件上“运行自定义工具”),您将创建所有实体类
- 在模型中,选择“从模型生成数据库”生成一个SQL文件,其中包含使用该模型创建新数据库所需的所有SQL语句。这一步还将在数据库和C代码之间创建所有必要的绑定。(所有这些都存在于幕后。)
IQueryable
开始在C代码中构建查询
您可以对模型进行更改,然后再次执行“从模型生成数据库”过程,以获得创建数据库的新SQL文件,但请注意,它将首先对任何现有数据库进行核化
context = new MyAppModels();
<connectionStrings>
<add name="MyAppConnection" connectionString="data source=(localdb)\mssqllocaldb;initial catalog=MyAppDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
</connectionStrings>