加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 实体框架TPC继承(请现在拍我)

发布时间:2020-12-16 09:38:12 所属栏目:asp.Net 来源:网络整理
导读:我正在尝试使用Code First和Migrations基于 http://www.schema.org上定义的实体密切构建实体模型和数据库.底线是所有实体都继承自实体“Thing”. 迁移构建数据库,但任何种子数据库的尝试都失败. 一切都来自Thing: namespace Entities.Models { public class
我正在尝试使用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; }
    }

}

解决方法

我目前正在使用类似的模型,我知道这个答案很晚,但它可能有所帮助.

首先,TPH,TPT和TPC是在我们的数据库中建模继承的机制.如果我们不需要为多态查询,更新或保存建模继承,我们不需要遵循TP *约定.

让我重申一下. TPH,TPT和TPC是可选的数据库继承建模策略.如果我们的应用程序不需要多态查询,更新或插入,我们不需要遵循TP *约定.

我的基本项目设置与您的非常相似.在我的项目中,我有一个抽象类,我的项目中的每个类都从该类继承.它被命名为XModelBase,我相信它对应于你的Thing类.

我使用这个抽象类来实现一些基本方法,这些方法将我的商业规则验证连接到Entity Framework的验证机制.此类还确保为每个实体捕获审计值,并且类包含其他通用属性(KeyId)以及为通用流程提供原型/模板.

我们的模型之间唯一真正的区别是,当您使用主键的Guid数据类型时,我的XModelBase有一个int作为主键的数据类型(所有类随后继承).

如果我是正确的,您和我将永远不需要执行如下查询:

场景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);

由于我们不需要适应场景1或场景2,因此我们不需要将事物作为单独的基表(TPT).我们也不需要或想要以TPC的隐形多态方式访问或保存我们的子类表;因此,当你考虑它时,我们真的永远不会需要以下属性:

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

当我们想要/需要建模多态关联时,我们在对象上下文中只需要这个DbSet属性.

从我们的上下文中删除该属性并删除基类的模型配置是继承自由的第一步.

接下来,我们将从子类模型配置中删除MapInheritedProperties(),因为将自动映射继承的属性.我们只保留.ToTable指定的子类对象.

同样,我的XModelBase基类主键有一个int,所以我可以用[Key]属性标记它,如:

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

但是因为我没有为我的XModelBase类创建表或使用DbSet,所以所有继承的子类都将具有独立的自动递增主键,这些主键在我的XModelBase类中使用此一个[Key]属性进行配置.

如果我正确地理解了您的问题,这些信息应该指向正确的方向,但如果我没有解决您的问题,我会很想知道您最终是如何解决问题的.

希望这可以帮助!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读