0

私は、EF 4.1 Code First との一種の「多重継承」関係をモデル化しようとしています。これが私がやろうとしていることの例です。

「User」オブジェクトを使用して、ユーザーがアプリケーションと対話する方法をモデル化しようとしているとしましょう。これは基本クラスであり、現在のユーザーが特に何もしていないとき (ホームページにアクセスするなど) に使用されます。次のようになります。

public class User
{
    public Guid ID { get; set; }    // Just use the forms authentication user ID
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

ここで、サイトの別の部分で同じユーザーの表現を作成したい場合、たとえば買い物客として、次のようになります。

public class Shopper : User
{
    public virtual ICollection<Orders> Orders { get; set; }
}

などなど。既存の User エントリを持つ Shopper を挿入しようとすると、PK が User テーブルに既に取得されているため、例外がスローされます。

この (IsA) 関係を EF Code First とモデル化する方法はありますか? それとも、このようなことで立ち往生するつもりですか?

public class Shopper
{
    public Guid UserID { get; set; }
    public virtual User User { get; set; }
    public virtual ICollection<Order> Orders { get; set; }

    public string FirstName
    {
        get { return User.FirstName; }
        set { User.FirstName = value; }
    }

    // yada, yada, yada...
}

Code First に固執し、DbContext で関係を正しくモデル化したいのですが、このようなことを行う方法がよくわかりません。ありがとう!

編集:

だから、私はこのようなことをしようとしています:

public void SomeMethod ()
{
    var UserID = Guid.NewGuid ();
    var MyUser = new User () { ID = UserID };
    SaveUserToDatabase (MyUser);

    var ShopperRepresentation = GetUserAsShopper (UserID);
    //  Do stuff.
}

基本的には、オブジェクト指向のロールを使用するのと同じだと思います。そのユーザーのすべての表現に同じ PK を使用したいのですが、すべての基本情報を User という基本クラスに格納します。もちろん、独自の SQL を記述すればこれが可能であることはわかっていますが、EF Code First でもそれが可能かどうかを確認したいと考えています。

4

1 に答える 1

1

はい、最初の 2 つのコード例で説明した方法で実行できます。

マッピングを定義する必要があるだけだと思います。これは、クラスを正しく設定することに加えて、OnModelCreating関数で実行する必要があります。DataContextその方法は、使用しているマッピング スキームによって異なります。私は最新のプロジェクトで Table-Per-Type (TPT) を使用したので、次のようなものがありました。

modelBuilder.Entity<User>().ToTable("Users");
modelBuilder.Entity<Shopper>().ToTable("Shoppers");
modelBuilder.Entity<OtherUser>().ToTable("OtherUsers");

うまくいかない場合はお知らせください。できることを確認いたします。

編集:

以下の説明を見て、それを行う方法が思いつきません。共通のデータを共有している場合でも、各オブジェクトを個別に保存する必要があります (EF で Shopper を Shopper と User ではなく Shopper として扱うようにする)。これにより、データの不一致が発生する可能性があります (たとえば、Shopper は LastName を更新したが、User は更新しなかった場合)。次のようなものを使用したほうがよいと思います。

public class User
{
    public virtual Guid ID { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual ShopperInfo { get; set; }
}

public class ShopperInfo
{
    public virtual ICollection<Order> Orders { get; set; }
}

次に、User を Shopper として扱う必要がある場合は、ShopperInfo にアクセスするだけです (存在しない場合は作成します)。EF は問題なく適切に設定できます。

ただし、多くのタイプのユーザーがいる場合は、面倒になる可能性があります. ただの提案ですが、少しきれいだと思います。

于 2011-05-18T19:33:35.880 に答える