0

最適な解決策がわからない問題があります。うまくいけば、ここの誰かが助けてくれる=)

私が解決しようとしているのは、システム、人、および組織でユーザーをタイプする必要があることです。2 つの共有ログイン テーブルが必要です (つまり、ユーザーは自分がどのタイプのユーザーであるかをおそらく知らないでしょう。ユーザー名とパスワードに関連しているだけです)。そこで、ユーザー名とパスワード用のログイン テーブルを作成しました。しかし、ログインが誰に接続されているかを知る必要があるため、個人または組織への参照が必要です。

次のクラスを考えてみましょう (簡略化)。

public class Login
{
    public string Username {get; set;}
    public string Password {get;set;}
}

public class LoginPerson : Login
{
    public Person Person {get;set;}
}

public class LoginOrg : Login
{
    public Organization Organization {get;set;}
}

public class Person
{
    public LoginPerson LoginPerson {get;set;}
    //Lots of other properties. Removed for simplicity
}

public class Organization
{
    public LoginOrg LoginOrg {get;set;}
    //Lots of other properties. Removed for simplicity
}

個人構成は次のように設定されます。

public class PersonConfiguration : EntityTypeConfiguration<Person>
    {
        public PersonConfiguration()
        {
            HasRequired(p => p.LoginPerson).WithRequiredPrincipal(p => p.Person);
        }
    }

まず、これがうまくいきません。「System.Data.EntityCommandCompilationException: System.Data.EntityCommandCompilationException: コマンド定義の準備中にエラーが発生しました。詳細については内部例外を参照してください。 ---> System.Collections.Generic.KeyNotFoundException: The given key was辞書に載っていない..」だから私の最初の質問は、なぜこれがうまくいかないのですか? 2 番目の質問は、この種の継承に最適な戦略はどれかということです。TPT、TPH、または TPC?

4

2 に答える 2

1

まず、どのエンティティもキーを持っていません。それらを機能させるには、主キーが必要です。EF はこれを行うために規則を使用します。これは、PersonId のように、クラス名と最後に Id を追加するか、属性を明示的に指定します。[Key]

第二に、あなたのモデルは紛らわしく、かなり循環的です。また、主キーがないと、関連付けを作成する方法がありません。

Person オブジェクトに LoginPerson のメンバーがあり、Organization にも同じメンバーがいる理由がわかりません。いずれにせよ、このモデルを再考し、キーが何であるかを理解する必要があります。

于 2013-08-29T18:05:55.633 に答える
0

私の例外に対する解決策は、正しい構成をセットアップすることでした ;-) PersonConfiguration には、LoginPerson プロパティの構成を含める必要はありませんでした。LoginPersonConfiguration を追加しました ->

public class LoginPersonConfiguration : EntityTypeConfiguration<LoginPerson>
{
    public LoginPersonConfiguration()
    {
        ToTable("LoginPerson");
        HasKey(l => l.Id);
        HasRequired(l => l.Person).WithOptional(p => p.LoginPerson).Map(t => t.MapKey("PersonId")); 
    }
}

また、ログインを DbContext クラスに追加する必要がありました

public class MyDbContext : DbContext
{
    public DbSet<Person> Persons { get; set; }
    public DbSet<Login> Logins { get; set; }
}

どの戦略が最適かということになると、TPT を選択することにしました。

于 2013-08-30T06:58:06.090 に答える