2012-10-19 69 views
3

我想在Visual Studio C#项目中创建我的第一个数据库并将实体添加到此数据库。我还没有设法做到这一点。在尝试时,我会在DbContext上致电SaveChanges()时获得DbUpdateException代码优先在实体框架保存时抛出DbUpdateException

我想保存下列实体:

public class TVSeriesReference : Reference 
{ 
} 

TVSeriesReference不只是继承Reference

public class Reference 
{ 
    /// <summary> 
    /// ID of the reference. 
    /// </summary> 
    public int Id { get; set; } 

    /// <summary> 
    /// Reference to the element in theTVDB. 
    /// </summary> 
    public int TheTVDBId { get; set; } 

    /// <summary> 
    /// Whether or not the reference has been marked as watched. 
    /// </summary> 
    public bool IsWatched { get; set; } 
} 

我现在用的是以下方面:

public class Library : DbContext 
{ 
    /// <summary> 
    /// Constructor using the base constructor. 
    /// This constructor names the database "Library". 
    /// </summary> 
    public Library() : base("Library") 
    { 
    } 

    /// <summary> 
    /// Set of TVSeriesReferences stored in the database. 
    /// </summary> 
    public DbSet<TVSeriesReference> TVSeriesReferences { get; set; } 

    /// <summary> 
    /// Set of SeasonReferences stored in the database. 
    /// </summary> 
    public DbSet<SeasonReference> SeasonReferences { get; set; } 

    /// <summary> 
    /// Set of EpisodeReferences stored in the database. 
    /// </summary> 
    public DbSet<EpisodeReference> EpisodeReferences { get; set; } 
} 

这是我如何尝试创建并将实体保存到da tabase。

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()会抛出以下异常:

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并通过该实体框架。

有没有人可以帮我把这个工作?

UPDATE:在app.config

<connectionStrings> 
    <add name="Library" 
     connectionString="Data Source=.\SQLEXPRESS" 
     providerName="System.Data.SqlServerCe.4.0"/> 
    </connectionStrings> 
+0

那么这个例外很明显是说数据库中没有'dbo.TVSeriesReferences'对象(我相信这是你试图更新的地方)。 – tpeczek

+0

但是不是实体框架应该创建数据库以及必要的表?如果不是,你能告诉我应该如何创建?我们的目标是在本地存储数据,并且只能在这个应用程序中使用(这不是必需的,但我相信这将是最简单的)。 – simonbs

+0

在此代码之前,您是否已初始化数据库? – IronMan84

回答

2

使用实体框架代码优先您仍然需要在您的app.config文件中设置适当的ConnectionString。例如,如果你想拥有一个本地数据库文件,你可以使用嵌入式SQL Server CE 4数据库引擎(当然可以使用代码首先可以与许多不同的数据库一起使用,包括SQL Server,SQL Server Express和MySQL):

<connectionStrings> 
    <add name="Library" connectionString="Data Source=|DataDirectory|CodeFirst.sdf" providerName="System.Data.SqlServerCe.4.0"/> 
</connectionStrings> 

在运行时,DataDirectory替换字符串将替换为应用程序当前执行环境的相应目录路径。如果没有DataDirectory替换字符串,应用程序将不得不以编程方式根据当前执行环境确定数据库文件的位置,然后动态构建连接字符串中使用的路径。

代码优先还具有自动重新创建功能,该功能由初始化策略控制。默认的初始化策略是CreateDatabaseIfNotExists。有了这个策略,如果你的ConnectionString指向的数据库不存在Code First会为你创建数据库,但是如果数据库已经存在Code First不会尝试创建它。

初始化策略可以用Database.SetInitializer()方法更改为以下之一:

这里需要记住,重新创建数据库将导致丢失那里存储的所有数据。

0

的ConnectionStrings您需要设置一个数据库初始化,然后初始化数据库。可能是最好的开始,因为这是一个新的数据库,DropCreateDatabaseAlways一个。你可以做到以下几点:

Database.SetInitializer(new DropCreateDatabaseAlways<Library>()); 
using(var db = new Library()) 
{ 
    db.Database.Initialize(true); 
} 

把一个连接字符串在App.config,像@tpeczek说,也将是一个好主意,做与此有关。

+0

EF设置CreateDatabaseIfNotExists的默认初始值设定项。除非你想改变它,否则你不需要设置初始化程序。即使这样,考虑使用Migrations也会更好。 –