【Entity framework】Code First Approach

开篇之前感谢 china_fucan的文章给我的帮助,下面的评论也解决了很多问题同样给予感谢.

code first

项目中的ORM框架如果采用的是EF,那么可能会采用code first的方式去使用EF.就是先将数据库的实体类,以及EF的核心DBContext写好之后, 运行程序会通过特定的数据库链接字符串在数据库中生成相应的table或数据.

创建一个code first demo

  • 使用vs新建一个console app
  • 创建一个class命名为Ef6RecipesContext,并且继承自DbContext.
using System.Data.Entity;
using DennisEFDemo.CodeFirstDemo.DBModels;

namespace DennisEFDemo.CodeFirstDemo.DBContext
{
    public class Ef6RecipesContext : DbContext
    {
        public DbSet<PictureCategory> PictureCategories { get; set; }
        public Ef6RecipesContext()
            : base("name=EF6CodeFirstRecipesContext")
        {
        }
        /// <summary>
        /// 在EF6RecipesContext中重写方法OnModelCreating配置双向关联(ParentCategory 和 SubCategories)
        /// </summary>
        /// <param name="modelBuilder"></param>
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<PictureCategory>().HasMany(t => t.Subcategories).WithOptional(t => t.ParentCategory);
        }
    }
}

  • 创建DB models PictureCategory
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace DennisEFDemo.CodeFirstDemo.DBModels
{
    [Table("PictureCategory", Schema = "dbo")]
    public class PictureCategory
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int CategoryId { get; private set; }
        public string Name { get; set; }
        public int? ParentCategoryId { get; private set; }
        [ForeignKey("ParentCategoryId")]
        public virtual PictureCategory ParentCategory { get; set; } //书中没有virtual关键字,这会导致导航属性不能加载,后面的输出就只有根目录!!
        public virtual List<PictureCategory> Subcategories { get; set; }
        public PictureCategory()
        {
            Subcategories = new List<PictureCategory>();
        }
    }
}

  • 在main函数中写一个静态方法
class Program
    {
        static void Main(string[] args)
        {
            RunExample();
            Console.ReadKey();

        }

        static void RunExample()
        {
            using (var context = new Ef6RecipesContext())
            {
                var louvre = new PictureCategory { Name = "Louvre" };
                var child = new PictureCategory { Name = "Egyptian ANTIQUITéS" };
                louvre.Subcategories.Add(child);
                child = new PictureCategory { Name = "Sculptures" };
                louvre.Subcategories.Add(child);
                child = new PictureCategory { Name = "Paintings" };
                louvre.Subcategories.Add(child);
                var paris = new PictureCategory { Name = "Paris" };
                paris.Subcategories.Add(louvre);
                var vacation = new PictureCategory { Name = "Summer Vacation" };
                vacation.Subcategories.Add(paris);
                context.PictureCategories.Add(paris);
                context.SaveChanges();
            }
            using (var context = new Ef6RecipesContext())
            {
                var roots = context.PictureCategories.Where(c => c.ParentCategory == null);
                roots.ToList().ForEach(root => Print(root, 0));
            }
        }
        static void Print(PictureCategory cat, int level)
        {
            StringBuilder sb = new StringBuilder();
            Console.WriteLine("{0}{1}", sb.Append(' ', level).ToString(), cat.Name);
            cat.Subcategories.ForEach(child => Print(child, level + 1));
        }
    }
  • 修改app.config文件(如果是web工程则为web.config)
<connectionStrings>
      <add name="EF6CodeFirstRecipesContext" connectionString="Data Source=stcav-235\stcav235;initial catalog=EF6Recipes;user id=sa;password=`*******`;" providerName="System.Data.SqlClient" />
  </connectionStrings>
  • 运行程序,会在数据库中创建相应的table并将数据写入后读取输出到控制台.
  • 源代码我会上传到git上,链接.

DBModelBuilder

上述代码中的Ef6RecipesContext类中有个DBModelBuilder,我查了一下文档, 一般使用这个类的EF项目基本上都是CODE FIRST approach.解释一下这玩意:

DbModelBuilder用于将CLR类映射到数据库模型.
这种以代码为中心的构建实体数据模型(EDM)模型的方法称为“代码优先(code first)”
DbModelBuilder通常用于通过重写DbContext.OnModelCreating(DbModelBuilder)来配置模型
还可以独立于DbContext使用DbModelBuilder来构建模型
但是,推荐的方法是在DbContext中使用OnModelCreating, 优点是工作流程更直观,可以处理常见任务,例如缓存创建的模型。形成模型的类型在DbModelBuilder中注册,可选配置,可以通过将数据注释应用于您的类和使用流畅的样式DbModelBuilder来执行API。

目前先写到这儿,上述内容有误还请点击下方图标联系我, 如有新内容会继续对此文进行更新,有兴趣的话可以保持关注.

N|Dennis

posted @ 2018-12-27 14:43  YanyuWu  阅读(155)  评论(0编辑  收藏  举报