4

Code FirstとMigrationsを使用して、 http: //www.schema.orgで定義されているエンティティに基づいて、エンティティモデルとデータベースを厳密に構築しようとしています。肝心なのは、すべてのエンティティがエンティティ「Thing」から継承されているということです。

移行によってデータベースが構築されますが、データベースをシードしようとしても失敗します。

すべてがThingから継承されます。

    namespace Entities.Models
    {
                public class Thing
                {
                    public Thing()
                    {            
                        Id = Guid.NewGuid();
                        Name = String.Empty;
                    }

                    public Guid           Id               { get; set; }
                    public virtual string Name             { get; set; }

                }

            public class Person : Thing
            {
                public Person()
                    : base()
                {
                    Friends = new List<Person>();
                }

                public string GivenName { get; set; }
                public string FamilyName { get; set; }
                public string Email { get; set; }

                public virtual ICollection<Person> Friends { get; set; }
            }

            public class Event : Thing
            {
                public Event()
                    : base()
                {
                    Attendees = new List<Person>();
                }

                public virtual ICollection<Person> Attendees { get; set; }
                public TimeSpan Duration { get; set; }
                public DateTime? endDate { get; set; }
                public DateTime? StartDate { get; set; }

            }

        public class ThingMap : EntityTypeConfiguration<Thing>
        {
            public ThingMap()
            {
                // Primary Key
                this.Property(t => t.Id)
                    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

                // Properties
                this.Property(t => t.Name)
                    .IsOptional()
                    .HasMaxLength(200);

                // Table & Column Mappings
                this.ToTable("entity_Thing");
          }
       }
    public class PersonMap : EntityTypeConfiguration<Person>
    {
        public PersonMap()
        {
            // Properties
            this.Map<Person>(t =>
            {
                t.MapInheritedProperties();
                t.ToTable("entity_Person");
            });

            // Table & Column Mappings
        }
    }

    public class EventMap : EntityTypeConfiguration<Event>
    {
        public EventMap()
        {
            // Properties
            this.Map<Event>(t =>
            {
                t.MapInheritedProperties();
                t.ToTable("entity_Event");
            });

            // Table & Column Mappings
        }
    }

    public class CitriusSpotsContext : DbContext
    {
        static CitriusSpotsContext()
        {
            Database.SetInitializer<CitriusSpotsContext>(null);
        }

        public CitriusSpotsContext()
            : base("Name=CitriusSpotsContext")
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new ThingMap());
            modelBuilder.Configurations.Add(new PersonMap());
            modelBuilder.Configurations.Add(new EventMap());
        }

        public DbSet<Thing> Things { get; set; }
        public DbSet<Person> People { get; set; }
        public DbSet<Event> Events { get; set; }
    }

}
4

2 に答える 2

3

私は現在同様のモデルを使用しています。この回答が遅れていることはわかっていますが、役立つ場合があります。

まず、TPH、TPT、およびTPCは、データベースの継承をモデル化するためのメカニズムです。ポリモーフィッククエリ、更新、または保存の継承をモデル化する必要がない場合は、TP*の規則に従う必要はありません。

言い直します。TPH、TPT、およびTPCは、オプションのデータベース継承モデリング戦略です。アプリケーションがポリモーフィックなクエリ、更新、または挿入を必要としない場合は、TP*の規則に従う必要はありません。

私の基本的なプロジェクト設定はあなたのものと非常によく似ています。私のプロジェクトには、プロジェクト内のすべてのクラスが継承する抽象クラスがあります。名前が付けられXModelBaseており、あなたのThingクラスに対応していると思います。

この抽象クラスを使用して、bizルールの検証をEntityFrameworkの検証メカニズムに結び付けるいくつかの基本メソッドを実装します。このクラスはまた、すべてのエンティティの監査値がキャプチャされていることを確認し、クラスは他のユニバーサルプロパティ(KeyId)を格納し、ユニバーサルプロセスのプロトタイプ/テンプレートを提供します。

私たちのモデル間の唯一の本当の違いは、主キーにデータ型を使用しXModelBaseintいるときに、主キーのデータ型として(すべてのクラスが後で継承する)を持っていることですGuid

私が正しければ、あなたと私は次のようなクエリを実行する必要はありません。

シナリオ1:

var query = from t in context.Things select t;

このタイプのクエリは、このシナリオでは意味がありません。データベース内のすべてのオブジェクトを選択するのはなぜですか?私たちはしませんし、しません

また、次のような抽象クラスを介してオブジェクトを保存することはありません。

シナリオ2:

var person = new Person() {Email = "something@somewhere.com"};
context.Things.Add(person);

代わりに、次のようにします。

シナリオ3:

var person = new Person() {Email = "something@somewhere.com"};
context.People.Add(person);

Scenario 1またはのどちらにも対応する必要がないため、個別のベーステーブル(TPT)であるScenario 2必要はありません。Thingsまた、TPCの目に見えない多態的な方法で、サブクラス化されたテーブルにアクセスしたり、保存したりする必要はありません。したがって、あなたがそれについて考えるとき、私たちは本当に次のプロパティを必要としません:

public DbSet<Thing> Things { get; set; }

このDbSetプロパティは、ポリモーフィックな関連付けをモデル化する必要がある場合にのみ、オブジェクトコンテキストで必要になります。

コンテキストからそのプロパティを削除し、基本クラスのモデル構成を削除することは、継承の自由への最初のステップです。

次に、MapInheritedProperties()継承されたプロパティが自動的にマップされるため、サブクラスのモデル構成からを削除します。.ToTableサブクラス化されたオブジェクトの指定はそのままにしておきます。

繰り返しになりますが、基本クラスの主キーint用にを持っているので、次のような属性でマークを付けることができます。XModelBase[Key]

[Key]
public int KeyId { get; set; }

ただし、テーブルを作成したりDbSetXModelBaseクラスに使用したりしていないため、継承するすべてのサブクラスには[Key]、クラス内のこの1つの属性で 構成された独立した自動インクリメントの主キーがありますXModelBase

私があなたの質問を正しく理解していれば、この情報はあなたを正しい方向に向けるはずですが、私があなたの質問に答えなかった場合、あなたがどのようにして問題を解決したのか知りたいです。

お役に立てれば!

于 2013-03-14T20:00:21.250 に答える
-2

コードファーストのアプローチに取り組んでいるようで、スキーマを c# クラスとして生成しようとしています。

コード ファーストを使用するには、基本クラスが DbContext から継承する必要があります。その後、データベース通信用の適切なメソッドを構築できます。

あなたの場合、Thing はリポジトリになるため、DbContext から継承する必要があります。その後、エンティティの作成を開始できます。

エンティティは単純なオブジェクト クラスであるため、他のクラスから継承できます。構造の例は次のようになります。

class Thing : DbContext
{
    public DbSet<Product> Products { get; set; }
}

class Product
{
    public int Id { get; set; }
    public int ProductName { get; set; }
}

詳細については、 http ://weblogs.asp.net/scottgu/archive/2010/07/23/entity-framework-4-code-first-custom-database-schema-mapping.aspxおよびhttp://www. codeproject.com/Articles/318010/Entity-Framework-Code-First-Let-s-Try-It

これが役立つことを願っています。

于 2012-12-24T19:27:37.597 に答える