global.asax ファイルに 2 つのデータベース初期化子があります。
1 つは、関連するテーブルを使用してデータベースを作成する必要があり、2 番目は単純なメンバーシップに必要なすべてのテーブルを初期化します。
私が抱えている問題は、DB を作成する最初の初期化メソッドが何もしないことです (少なくともそのように見えます)。シンプルなメンバーシップ初期化子は正常に機能します。
コンテキストから作成したいテーブルは、リポジトリ クラス内でコンテキストの新しいインスタンスが作成されたときにのみ作成されます。WebSecurity.InitialiseDatabaseConnection
イニシャライザがすでに作成しているため、すでに存在するユーザープロファイルテーブルを作成しようとしているため、これは失敗しますか?
リポジトリメソッドでコンテキストが作成されるまで、最初のデータベース初期化子が実行されない理由について何か考えはありますか?
データベースは SQL Server LocalDB です。
これが私のApplication_Start
方法ですGlobal.asax.cs
:
protected void Application_Start()
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Configuration>());
WebSecurity.InitializeDatabaseConnection("MyDb", "UserProfile", "UserId", "UserName", autoCreateTables: true);
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new RazorViewEngine());
}
Context クラスは次のとおりです。
public class MyContext : DbContext
{
public MyContext()
: base("name=MyDb")
{
}
public DbSet<MyEntity> myEntity{ get; set; }
public DbSet<UserProfile> UserProfiles { get; set; }
}
そして、ここにリポジトリメソッドがあります:
using (var db = new MyContext())
{
var user = _userRepository.GetUserByUserName(userName);
db.UserProfiles.Attach(user);
if (rack.Id == 0)
{
rack.DateAdded = DateTime.Now;
rack.AddedBy = user;
db.MyEntity.Attach(rack);
db.Entry(rack).State = EntityState.Added;
db.SaveChanges();
}
else
{
db.MyEntity.Attach(rack);
db.Entry(rack).State = EntityState.Modified;
db.SaveChanges();
}
}
編集: 以下のように、SimpleMembership イニシャライザを構成クラスのシード メソッドに移動しました。これにより、テーブルが正しい順序で作成されるという問題が解決されますが、データベースが取得されない理由についてはまだ賢明ではありません。Application_Start
メソッドで初期化子が呼び出されたときに初期化される
protected override void Seed(RackTrackContext context)
{
WebSecurity.InitializeDatabaseConnection("MyDb", "UserProfile", "UserId", "UserName", autoCreateTables: true);
if (!Roles.RoleExists("Administrator"))
Roles.CreateRole("Administrator");
if (!WebSecurity.UserExists("User1"))
WebSecurity.CreateUserAndAccount(
"User1",
"CodeMonkey"
);
if (!Roles.GetRolesForUser("User1").Contains("Administrator"))
Roles.AddUsersToRoles(new[] { "User1" }, new[] { "Administrator" });
}
編集 No2:
それを機能させるために、Application_start メソッドで新しいコンテキストを作成し、db から結果を取得しました。これにより、適用したい段階で移行が適用されます。
それは厄介で、醜く、賞を受賞することはありませんが、ちょっとうまくいき、それをしている間に動物が傷つけられなかったので、そうです.
protected void Application_Start()
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Configuration>());
//this code is here to ensure that the context is created and migrations applied,
//prior to the user seeing the start screen for the app. Must be a better way of doing it....
using (var db = new MyContext())
{
var results = db.MyEntity.FirstOrDefault();
}
誰かが私にもっと良い方法を教えてくれるなら、何人かの担当者が手に入れようとしています!