• 在Code First中自动创建Entity模型


    之前我在博客文章中介绍过如何使用Code First来创建数据库,通过CodeFirst的方式,可以大幅的减少开发人员的工作量,比传统的先创建库再ORM的方式简单了不少。但是,很多时候,特别是一些MIS系统,我们会涉及到大量的实体类型,类似如下所示:

        public class DbContext : System.Data.Entity.DbContext
        {
            public DbContext() : base("name=DefaultConnection")
            {
            }

            public DbSet<Pencil> Penlils { get; set; }
            public DbSet<Pen> Pens { get; set; }
            public DbSet<Ink> Inks { get; set; }
            public DbSet<Eraser> Erasers { get; set; }

            //....
        }

    在常用的CodeFirst方式下,每增加一种类型就需要在DbContext中增加一个属性。虽然并不算麻烦,但这种手动维护的方式存在如下两个问题:

    1. 当实体类型较多且变更比较频繁的的时候,靠手动的方式维护实体列表很容易出错。
    2. 有的时候,客户并不会买整套产品,只需要里面的部分模块,手动维护的方式不方便模块的裁剪。

    此时,就需要我们来实现动态创建实体模型了,Entity Framework中本身是支持动态创建实体模型的,上面的实体模型就可以通过如下方式动态创建:

        public class DbContext : System.Data.Entity.DbContext
        {
            public DbContext() : base("name=DefaultConnection")
            {
            }

            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);

                modelBuilder.Entity<Pencil>();
                modelBuilder.Entity<Pen>();
                modelBuilder.Entity<Ink>();
                modelBuilder.Entity<Eraser>();
                //....
            }
        }

    PS:修改成这样的方式后,原来的代码可能出现如下问题:DbContext中没有 Inks属性了。此时只需要将原来的对db.Inks的访问换成 db.Set<Ink>即可

    结果上述操作后,虽然我们实现了动态创建,但实体类型还是手动添加的。因此我们还缺少一种实体类型的发现机制,这种发现机制在.net中实现还是比较简单的,这里我采用的是Attribute的方式。

    首先写一个Attribute,

        [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
        public class PersistentAttribute : Attribute
        {
        }

    然后将需要自动创建的实体用该Attribute标记,

        [Persistent]
        public class Pen

        [Persistent]
        public class Ink

    最后,根据标记的实体添加实体模型。

        public class DbContext : System.Data.Entity.DbContext
        {
            public DbContext() : base("name=DefaultConnection")
            {
            }

            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);

                var assembly = this.GetType().Assembly;
                var entityTypes = from type in assembly.GetTypes()
                                 where type.GetCustomAttribute<PersistentAttribute>() != null
                                 select type;

                var entityMethod = typeof(DbModelBuilder).GetMethod("Entity");

                foreach (var type in entityTypes)
                {
                    entityMethod.MakeGenericMethod(type).Invoke(modelBuilder, new object[] { });
                }
            }
        }

    通过上述方法,就可以实现实体模型的自动创建了。当然仅仅这样还不大够,我们的实体模型往往还对应着一个Controller,下一篇文章就介绍一下如何实现自动创建Controller。

  • 相关阅读:
    MAC配置DNS服务器
    真机IOS8.3以上的文件夹共享
    appium + python的环境配置_windows
    python 的时间与日期
    sublimetext 2 编译文件带input时 提示 EOFError: EOF when reading a line
    cmd无法输入中文解决方案
    配置python学习环境遇到的问题:[Decode error
    monkey初接触
    Android logcat输出中文乱码
    运行 命令框不记录打过的命令,重启后CMD里面是空的.上次打过的命令消失了.
  • 原文地址:https://www.cnblogs.com/TianFang/p/3813292.html
Copyright © 2020-2023  润新知