4

UserProfileテーブルへのカスタムデータの追加に関するこの優れたブログを読んだ後、UserProfileテーブルがデフォルトデータとすべての追加情報が格納される別のクラスを格納する方法を変更したいと思いました。

Interenetアプリケーションテンプレートを使用して新しいプロジェクトを作成した後、2つのクラスを作成しました。

Student.cs

[Table("Student")]
public class Student
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public virtual int StudentId { get; set; }
    public virtual string Name { get; set; }
    public virtual string Surname { get; set; }
    public virtual int UserId { get; set; }
}

UserProfile.cs

[Table("UserProfile")]
public class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string UserName { get; set; }
    public virtual int StudentId { get; set; }
    public virtual Student Student { get; set; }
}

また、AccountModel.csからUserProfile定義を削除しました。私のDBコンテキストクラスは次のようになります。

MvcLoginDb.cs

public class MvcLoginDb : DbContext
{
    public MvcLoginDb()
        : base("DefaultConnection")
    {
    }

    public DbSet<UserProfile> UserProfiles { get; set; }
    public DbSet<Student> Students { get; set; }
}

繰り返しになりますが、AccountModel.csからdbコンテキスト定義を削除しました。

私が書いたパッケージ-マネージャー-コンソールの内部:

Enable-Migrations

私のConfiguration.csは次のようになります。

internal sealed class Configuration : DbMigrationsConfiguration<MvcLogin.Models.MvcLoginDb>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
    }

    protected override void Seed(MvcLogin.Models.MvcLoginDb context)
    {
        WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);

        if (!WebSecurity.UserExists("banana"))
            WebSecurity.CreateUserAndAccount(
                "banana",
                "password",
                new
                {
                   Student = new Student { Name = "Asdf", Surname = "Ggjk" }
                });

    }
}

これは、新しいクラスを作成するときに学生データを追加するというアイデアでしたが、 Update-Database -Verboseを実行した後、エラーが発生する ため、このアプローチは機能しません:オブジェクトタイプMvcLogin.Models.Studentから既知の管理対象へのマッピングが存在しませんプロバイダーのネイティブタイプ。

このエラーが発生する理由を誰かが説明できますか?別のテーブルに追加のデータを格納するために別のアプローチを使用する必要がありますか?

4

2 に答える 2

3

私は同じ問題で多くの苦労をしました。重要なのは、UserProfile クラスと Student クラスの関係を正しくすることです。正しく機能するには、1 対 1 の関係でなければなりません。

これが私の解決策です:

Person.cs

public class Person
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    /* and more fields here */

    public virtual UserProfile UserProfile { get; set; }
}

UserProfile.cs

public class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string UserName { get; set; }

    public virtual Person Person { get; set; }
}

MyDbContext.cs

public class MyDbContext : DbContext
{
    public DbSet<Person> Person { get; set; }
    public DbSet<UserProfile> UserProfile { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
     modelBuilder.Entity<UserProfile>()
                    .HasRequired(u => u.Person)
                    .WithOptional(p => p.UserProfile)
                    .Map(m => m.MapKey("PersonId"));
    }
}

ただし、WebSecurity.CreateUserAndAccount メソッドを使用してユーザーを作成することにも苦労しました。そのため、Entity Framework を使用して Person オブジェクトを作成し、メンバーシップ プロバイダー メソッドを使用してユーザー アカウントを作成しました。

AccountRepository.cs

 public Person CreatePerson(string name, string username) {

     Person person = new Person { Name = name };
     _dbContext.Person.add(person);
     _dbContext.SaveChanges();

     var membership = (SimpleMembershipProvider)Membership.Provider;
     membership.CreateUserAndAccount(
         model.UserName, 
         createRandomPassword(), 
         new Dictionary<string, object>{ {"PersonId" , person.Id}}
     );

 }
于 2013-03-14T21:35:07.743 に答える
0

HenningJ、同じことに対する答えを探しています。残念ながら (ご存じだと思いますが) これを行った方法の問題は、SQL トランザクションがないことです。SaveChanges() または CreateUserAndAccount() のいずれかが失敗し、ユーザー データベースが無効な状態になる可能性があります。失敗した場合はロールバックする必要があります。

私はまだ最終的な答えを探していますが、最終的な解決策を投稿します。カスタム メンバーシップ プロバイダーを作成する必要がないように (もう一度!) 期待していますが、その方が速いと考え始めています。

于 2013-07-19T20:41:04.987 に答える