3

Visual Studio C# プロジェクトで最初のデータベースを作成し、このデータベースにエンティティを追加しようとしています。私はまだそうすることができませんでした。しようとすると、 をDbUpdateException呼び出すとが表示SaveChanges()されDbContextます。

次のエンティティを保存しようとしています:

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

これが、エンティティを作成してデータベースに保存しようとする方法です。

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 をインストールし、それを介して Entity Framework をインストールしました。

これを機能させるのを手伝ってくれる人はいますか?

UPDATE : ConnectionStrings のapp.config

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

2 に答える 2

2

Entity Framework Codeで作業している間、最初にファイルに適切なConnectionStringを設定する必要がありapp.configます。たとえば、ローカルデータベースをファイルに保存する場合は、組み込みの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と、アプリケーションは現在の実行環境に基づいてデータベースファイルの場所をプログラムで決定し、接続文字列で使用されるパスを動的に構築する必要があります。

コードファーストには、初期化戦略によって制御される自動再作成機能もあります。デフォルトの初期化戦略はCreateDatabaseIfNotExistsです。この戦略では、ConnectionStringが存在しないデータベースを指している場合、Code Firstがデータベースを作成しますが、データベースがすでに存在する場合、CodeFirstはデータベースを作成しようとしません。

初期化戦略は、Database.SetInitializer()メソッドを使用して次のいずれかに変更できます。

ここで覚えておく必要があるのは、データベースを再作成すると、そこに保存されていたすべてのデータが失われることです。

于 2012-10-19T17:23:20.920 に答える
0

データベース初期化子を設定してから、データベースを初期化する必要があります。これは新しいデータベースであるため、おそらく最初に使用するのに最適なデータベースは DropCreateDatabaseAlways です。次のことができます。

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

@tpeczekが言ったように、App.configに接続文字列を入れることも、これを行うことをお勧めします。

于 2012-10-19T13:52:55.820 に答える