3

レガシ データベースに対して Entity Framework 4.1 を使用すると、複数形化されておらず、共通の主キーに異なる名前を使用する TPT 継承モデルのワーキング セットを生成できません。

以下に示すように、データベース テーブル Organization、Account、および Company を使用しています。

Organization
  OrganizationID (int PK)
  OrgName (varchar)

Company
  CompanyID (int PK)
  CompanyNo (varchar)

Account
  AccountID (int PK)
  AccountNo (varchar)

Account.AccountID と Company.CompanyID には、これらの列の値が Organization.OrganizationID にも含まれている必要があるという FK 制約があるため、Organization 行がないとどちらも存在できません。これらのテーブルを最初から設計していた場合、Account と Company の両方が代わりに OrganizationID を主キーとして使用します。

public partial class BusinessEntities : DbContext
{
    public BusinessEntities()
        : base("name=BusinessEntities")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Organization>().ToTable("Organization");

        // Override pluralization
        modelBuilder.Entity<Company>().ToTable("Company");
        modelBuilder.Entity<Account>().ToTable("Account");

        // Set primary key column for each
        modelBuilder.Entity<Company>().Property(
            e => e.OrganizationID).HasColumnName("CompanyID");
        modelBuilder.Entity<Account>().Property(
            e => e.OrganizationID).HasColumnName("AccountID");
    }

    public DbSet<Organization> Organization { get; set; }
}

public partial class Organization
{
    public int OrganizationID { get; set; }
    public string OrgName { get; set; }
}

public partial class Account : Organization
{
    public string AccountNo { get; set; }
}

public partial class Company : Organization
{
    public string CompanyNo { get; set; }
}

以下に示す単純な選択コードを使用しようとすると、エラーが発生します。

プロパティ 'OrganizationID' は、タイプ 'Company' で宣言されたプロパティではありません。Ignore メソッドまたは NotMappedAttribute データ注釈を使用して、プロパティがモデルから明示的に除外されていないことを確認します。有効なプリミティブ プロパティであることを確認してください。

static void Main(string[] args)
{
    using (var context = new BusinessEntities())
    {
        foreach (var b in context.Organization.OfType<Company>())
        {
            Console.WriteLine("{0} {1}", b.CompanyNo, b.OrgName);
        }

        foreach (var b in context.Organization.OfType<Account>())
        {
            Console.WriteLine("{0} {1}", b.AccountNo, b.OrgName);
        }
    }
    Console.ReadLine();
}
4

1 に答える 1

2

ここでTPTマッピングについて説明しました。ステップバイステップなので機能するはずですが、子エンティティのIDをマッピングする必要があります。

ただし、問題は、Model-firstから開始し、EDMXに依存するDdContextを生成してから、そのEDMXを削除し、自分でマッピングの定義を開始することです。モデルファーストとコードファーストのどちらを使用するかを決定する必要があります。あなたはEDMXであなたの努力を無駄にしました。

DbContextでModel-firstを使用する方法を知りたい場合は、この記事を確認してください。コードファーストを使用する場合は、EDMXを作成せず、この記事に従って継承をマップしてください。

于 2011-03-30T20:02:41.860 に答える