簡體   English   中英

使用Entity Framework的Code First在保存時會拋出DbUpdateException

[英]Code First with the Entity Framework throws a DbUpdateException when saving

我正在嘗試在Visual Studio C#項目中創建我的第一個數據庫,並將實體添加到此數據庫。 我還沒有設法這樣做。 在嘗試時,我會在DbUpdateException調用SaveChanges()時得到DbContext

我想保存以下實體:

public class TVSeriesReference : Reference
{
}

TVSeriesReference除了繼承Reference TVSeriesReference什么TVSeriesReference做:

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; }
}

這就是我嘗試創建實體並將其保存到數據庫的方法。

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並通過該實體框架。

有沒有人可以幫助我讓這個工作?

更新app.config ConnectionStrings

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

在使用Entity Framework Code First時,您仍需要在app.config文件中設置正確的ConnectionString。 例如,如果要在文件中包含本地數據庫,則可以使用嵌入式SQL Server CE 4數據庫引擎(當然Code First可以與許多不同的數據庫一起使用,包括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替換字符串,您的應用程序必須以編程方式根據當前執行環境確定數據庫文件的位置,然后動態構建連接字符串中使用的路徑。

Code First還具有自動重新創建功能,該功能由初始化策略控制。 默認初始化策略是CreateDatabaseIfNotExists 使用此策略如果您的ConnectionString指向不存在的數據庫, Code First將為您創建數據庫,但如果數據庫已存在,則Code First將不會嘗試創建它。

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

您需要記住,重新創建數據庫將導致丟失存儲在那里的所有數據。

您需要設置數據庫初始化程序,然后初始化數據庫。 可能是最好的開始,因為這是一個新的數據庫,DropCreateDatabaseAlways一個。 您可以執行以下操作:

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

將連接字符串放在App.config中,就像@tpeczek所說,這也是一個好主意。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM