Entity Framework のコード ファーストの概念を使用して、新しいデータベースを作成しようとしています。ただし、コードを実行すると、データベースは (DropCreateDatabaseIfModelChanges
設定を使用して) 作成されませんが、コードは正常に実行されます。データベースから何かを取得しようとすると、次の例外が発生します。
私のプロジェクトはDataAccess
、一般的なサービスとリポジトリの構築を備えた別のレイヤーを使用してセットアップされています。したがって、すべてのエンティティ、リポジトリ、およびデータベース コンテキストは、ソリューション内の別のプロジェクトにあります。
私のglobal.asax
ファイルには、次のコードが含まれています。
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MyContext>());
存在しない場合、これは新しいデータベースを初期化するはずですよね?
私のデータベース コンテキスト クラスは次のようになります。
namespace Website.DAL.Model
{
public class MyContext : DbContext
{
public IDbSet<Project> Projects { get; set; }
public IDbSet<Portfolio> Portfolios { get; set; }
/// <summary>
/// The constructor, we provide the connectionstring to be used to it's base class.
/// </summary>
public MyContext()
: base("MyConnectionString")
{
}
static MyContext()
{
try
{
Database.SetInitializer<MyContext>(new DropCreateDatabaseIfModelChanges<MyContext>());
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// This method prevents the plurarization of table names
/// </summary>
/// <param name="modelBuilder"></param>
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.PluralizingTableNameConvention>();
}
}
}
インターネット上のいくつかのチュートリアルと記事に従って、このクラスを作成しました。それは私にとってすべて新しいことですが、私が見る限り、これまでのところすべてが正しいようです. だから今私が使用している2つのエンティティ。それらは「プロジェクト」と「ポートフォリオ」と呼ばれます。彼らはこのように見えます。
public class Portfolio
{
[Key]
public Guid Id { get; set; }
public String Name { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public bool IsPublished { get; set; }
public virtual ICollection<Project> Projects { get; set; }
}
と
public class Project
{
[Key]
public Guid Id { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public bool IsPublished { get; set; }
public String Title { get; set; }
}
私が使用しているデータベースは外部サーバーで実行されており、使用しているホスティング プロバイダーに付属しています。SQL Server データベースを稼働させており、データベースへの接続文字列web.config
は Web サイト プロジェクトの中にあります。私はすでにデータベースを削除しようとしましたが、残念ながらうまくいきませんでした。ここで明らかな何かが欠けていますか?それとも、データベースを作成するためのサーバーへのアクセス権のような単純なものでしょうか?
注:Database-Update -Script
コマンドを実行して SQL コードを生成すると、すべてのテーブルを作成するための正しい SQL ステートメントが作成されたようです。
更新 1: いくつかのコメントのおかげで、私はもう少し先に進みました。いくつかの変更を強制するためにエンティティに 2 つのプロパティを追加し、次のようなカスタム初期化子も作成しました。
public class ForceDeleteInitializer : IDatabaseInitializer<MyContext>
{
private readonly IDatabaseInitializer<MyContext> _initializer = new DropCreateDatabaseIfModelChanges<MyContext>();
public ForceDeleteInitializer()
{
//_initializer = new ForceDeleteInitializer();
}
public void InitializeDatabase(MyContext context)
{
//This command is added to prevent open connections. See http://stackoverflow.com/questions/5288996/database-in-use-error-with-entity-framework-4-code-first
context.Database.ExecuteSqlCommand("ALTER DATABASE borloOntwikkel SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
_initializer.InitializeDatabase(context);
}
}
また、コンテキストのコンストラクターから初期化子を削除したので、これは、このコード行を削除したことを意味します。
Database.SetInitializer<MyContext>(new DropCreateDatabaseIfModelChanges<MyContext>());
その後、これら 3 行を Global.asax ファイルに追加しました。
Database.SetInitializer(new ForceDeleteInitializer());
MyContext c = new MyContext();
c.Database.Initialize(true);
デバッグすると、この例外が発生します。
これにより、次の情報が得られます。
- InnerException は言う: プロバイダーは ProviderManifestToken を返さなかった
- InnerException の InnerException は次のように述べています。開いていない接続」
これらのアクションの後、データベースにアクセスできなくなるため、おそらく削除されます..
これについて何ができるでしょうか?もちろん、ホスティング プロバイダーが適切なアクセス権を与えないため、master データベースにアクセスできない可能性が最も高いです。