5

EF CTP5コードを使用-最初に、あるクラスに複数のコレクションを含み、別のクラスを指すクラスモデルをマッピングしようとしています。これが私が意味することの例です:

public class Company
{
    public int CompanyId { get; set; }
    public IList<Person> FemaleEmployees { get; set; }
    public IList<Person> MaleEmployees { get; set; }
}

public class Person
{
    public int PersonId { get; set; }
    public Company Company { get; set; }
}

DbContext次のように、さらにカスタマイズせずにこのモデルからデータベースを作成させると、次のようになります。

public class MyContext : DbContext
{
    public DbSet<Company> Companies { get; set; }
    public DbSet<Person> People { get; set; }
}

...次に、SQL Serverに2つのテーブルがあります。1つの列Companiesのみの単純なテーブルと次の列のテーブルです(「FKRN」は、SQL ServerのEFによって作成された「外部キー関係名」を意味します)。CompanyIdPeople

PersonId            int     not nullable
CompanyCompanyId    int     nullable       FKRN: Company_FemaleEmployees
CompanyCompanyId1   int     nullable       FKRN: Company_MaleEmployees
CompanyCompanyId2   int     nullable       FKRN: Person_Company

CompanyId最後の3つの列には、テーブルの主キーとのすべての外部キー関係がありCompaniesます。

今、私はいくつかの質問があります:

  • 1)テーブルに3つの外部キー列があるのはなぜですか?People私は実際に2つを期待していました。3番目の列public Company Company { get; set; }からプロパティを削除すると消えますが、クラスの参照プロパティも失われます。PersonCompanyCompanyId2

  • Company2)プロパティをテーブルから削除したとしPersonます(モデルでは実際には必要ありません)。CompanyCompanyId残りの2つの外部キー列に自動作成およびとは別の名前を付ける方法はありCompanyCompanyId1ますか?(たとえば、FCompanyIdおよびコレクションとMCompanyIdの関係を示すために。)FemaleEmployeesMaleEmployees

  • CompanyId3)テーブルに1つの外部キーのみを使用してこのモデルを定義する方法はありPeopleますか?確かに、Personクラス内に差別化する追加の列が必要になります(のようにbool IsFemale)。PersonはFemaleEmployeesまたはMaleEmployeesコレクションのいずれかであり、両方に含まれることはありません(この例では当然)。したがって、SQLを使用すると、のようなものでこれらのコレクションをフェッチできますWHERE IsFemale = true/false AND CompanyId = 1。この方法で2つのコレクションをロードするためのヒントをEntityFrameworkに与えることができるかどうか疑問に思っています。(ここでは、両方が派生するaFemalePersonとclassによってモデルを拡張することは避けたいと思います。MalePersonPersonこれらの派生クラスは空で人工的であり、SQL Serverへのマッピングを有効にする以外の目的はなかったため、基本クラスとして使用し、たとえばTable-Per-Hierarchyマッピングを使用します。)外部キーCompanyIdが1つしかない場合は、それを作成できnon-nullableます。 2つの外部キーでは不可能です(同じ行で両方がnull以外になることはありません)。

事前にフィードバックや提案をありがとうございます!

4

2 に答える 2

3
  • 質問(1):EFは、Companyクラス内の単一の参照プロパティPersonを2つの異なるコレクションエンドポイントFemaleEmployeesに同時にマップすることはできません。マッピング規則は、モデルで公開されていない3番目のエンドポイントが実際に存在することを前提としています。したがって、3番目の外部キーが作成されます。MaleEmployeesCompanyCompany

  • 質問(2):EF 4.1リリース候補では、クラスのMapメソッドを使用して、Fluent APIで外部キーのデータベース列名を指定できるようになりました(EF CTP5では不可能でした) 。ForeignKeyNavigationPropertyConfiguration

    modelBuilder.Entity<Company>()
                .HasMany(c => c.FemaleEmployees)
                .WithOptional()
                .Map(conf => conf.MapKey("FCompanyId"))
                .WillCascadeOnDelete(false);
    
    modelBuilder.Entity<Company>()
                .HasMany(c => c.MaleEmployees)
                .WithOptional()
                .Map(conf => conf.MapKey("MCompanyId"))
                .WillCascadeOnDelete(false);
    
  • 質問(3)へ:私はまだわかりません。

編集

この古い質問を今すぐ閉じるだけです:(3)(1つのエンティティの2つのナビゲーションプロパティを別のエンティティの同じエンドポイントに関連付ける)は不可能です。たとえば、特定のエンティティフレームワークコードを最初に多から2へのモデルマッピング...(およびI成功せずにそのようなシナリオの解決策を探していた他の多くの質問を覚えておいてください)

于 2011-03-16T18:43:48.987 に答える
2

私はあなたがこれを行うことができると思います:

public class Company
{
    public int CompanyId { get; set; }
    public ICollection<Person> Employees { get; set; }
    public IEnumerable<Person> MaleEmployees {
        get
        {
            Employees.Where(x=> !x.IsFemale);
        }
    }
}

public class Person
{
    public int PersonId { get; set; }
    public Company Company { get; set; }
}

PeopleテーブルにCompanyIDFKが1つだけあります。

EFコンテキストを使用して男性従業員をロードできます。

context.Entry(companyInstance)
    .Collection(p => p.Employees)
    .Query()
    .Where(u => !u.IsFemale)
    .Load();

Company.FemaleEmployeesに男性を追加するとどうなるので、あなたのアプローチはあまり良くないと思います。EFはこのルールを知らない

于 2011-02-23T12:03:19.833 に答える