使用Entity Framework的Code First在保存时会抛出DbUpdateException
我正在尝试在Visual Studio C#项目中创建我的第一个数据库,并将实体添加到此数据库。 我还没有设法这样做。 在尝试时,我会在DbUpdateException
调用SaveChanges()
时得到DbContext
。
我想保存以下实体:
public class TVSeriesReference : Reference { }
TVSeriesReference
除了inheritanceReference
TVSeriesReference
什么TVSeriesReference
做:
public class Reference { /// /// ID of the reference. /// public int Id { get; set; } /// /// Reference to the element in theTVDB. /// public int TheTVDBId { get; set; } /// /// Whether or not the reference has been marked as watched. /// public bool IsWatched { get; set; } }
我使用以下上下文:
public class Library : DbContext { /// /// Constructor using the base constructor. /// This constructor names the database "Library". /// public Library() : base("Library") { } /// /// Set of TVSeriesReferences stored in the database. /// public DbSet TVSeriesReferences { get; set; } /// /// Set of SeasonReferences stored in the database. /// public DbSet SeasonReferences { get; set; } /// /// Set of EpisodeReferences stored in the database. /// public DbSet EpisodeReferences { get; set; } }
这就是我尝试创建实体并将其保存到数据库的方法。
using (var db = new Library()) { var reference = new TVSeriesReference { Id = 2, TheTVDBId = 1, IsWatched = true }; db.TVSeriesReferences.Add(reference); try { db.SaveChanges(); } catch (DbUpdateException e) { Debug.WriteLine("\n\n*** {0}\n\n", e.InnerException); } }
db.SaveChanges()
将抛出以下exception:
System.Data.UpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Invalid object name 'dbo.TVSeriesReferences'. at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData() at System.Data.SqlClient.SqlDataReader.get_MetaData() at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) at System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator translator, EntityConnection connection, Dictionary`2 identifierValues, List`1 generatedValues) at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) --- End of inner exception stack trace --- at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) at System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache) at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options) at System.Data.Entity.Internal.InternalContext.SaveChanges()
我现在已经把我的头发撕成了几个小时,我无法弄清楚我做错了什么。 似乎没有创建表(或者整个数据库?)。 在这个工作之前,我应该设置或安装了什么? 我已经安装了NuGet并通过该entity framework。
有没有人可以帮助我让这个工作?
更新 : app.config
ConnectionStrings
在使用Entity Framework Code First时,您仍需要在app.config
文件中设置正确的ConnectionString。 例如,如果要在文件中包含本地数据库,则可以使用嵌入式SQL Server CE 4数据库引擎(当然Code First可以与许多不同的数据库一起使用,包括SQL Server,SQL Server Express和MySQL):
在运行时, DataDirectory
替换字符串将替换为应用程序当前执行环境的相应目录路径。 如果没有DataDirectory
替换字符串,您的应用程序必须以编程方式根据当前执行环境确定数据库文件的位置,然后动态构建连接字符串中使用的路径。
Code First还具有自动重新创建function,该function由初始化策略控制。 默认初始化策略是CreateDatabaseIfNotExists 。 使用此策略如果您的ConnectionString指向不存在的数据库, Code First将为您创建数据库,但如果数据库已存在,则Code First将不会尝试创建它。
可以使用Database.SetInitializer()
方法将初始化策略更改为以下之一:
- DropCreateDatabaseAlways
- DropCreateDatabaseIfModelChanges
- MigrateDatabaseToLatestVersion
您需要记住,重新创建数据库将导致丢失存储在那里的所有数据。
您需要设置数据库初始化程序,然后初始化数据库。 可能是最好的开始,因为这是一个新的数据库,DropCreateDatabaseAlways一个。 您可以执行以下操作:
Database.SetInitializer(new DropCreateDatabaseAlways()); using(var db = new Library()) { db.Database.Initialize(true); }
将连接字符串放在App.config中,就像@tpeczek所说,这也是一个好主意。