zoukankan      html  css  js  c++  java
  • 第二篇:Entity Framework CodeFirst & Model 映射

        前一篇 第一篇:Entity Framework 简介 我有讲到,ORM 最关键的 Mapping,也提到了最早实现Mapping的技术,就是 特性 + 反射,那Entity Framework 实现Mapping 又是怎样的呢? EntityFramework 实现Mapping 有两种方式。

        1. 数据注解(DataAnnotations)

        2. Fluent API

    一. 数据注解,这种方式,就是在实体和属性加上一些EntityFramework 定义好的一些特性,然后EntityFramework,在具体操作数据库时进行反射。跟我们上篇提到 特性+反射 一样的方案。因此今天不会在这篇讲 DataAnnotations 。会贴一点实例代码。

    比较要注意的是,实现 DataAnnotations ,要引用 System.ComponentModel.DataAnnotations 命名空间。

    实例代码如下,特殊说明一下,EntityFramework 支持 .Net 可为空表达法,如 int?,DateTime? 。下面代码 最后修改时间 LastModifiedDateTime 就是这样。

     

     

    using System;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace EntityFrameworkSample.Models
    {
        [Table("Sample_Order")] //标示为 表名
        //[Table("Sample_Order", Schema = "dbo")] //标示为 表名 ,表的拥有者
        public class OrderModel
        {
            [Key]//标示为 主键
            [DatabaseGenerated(DatabaseGeneratedOption.Identity)] // 标示为 自动增量
            public Guid OrderGuid { get; set; }
            [Required] //标示为 必填
            [MaxLength(30)] //标示为 字符串长度最大30
            public string OrderNo { get; set; }
            [Required] //标示为 必填
            [MaxLength(20)] //标示为 字符串长度最大30
            public string OrderCreator { get; set; }
            [Required]
            [DatabaseGenerated(DatabaseGeneratedOption.Identity)] // 标示为 自动增量 数据库有默认值 getdate()
            public DateTime OrderDateTime { get; set; }
            [Required]
            public string OrderStatus { get; set; }
            [MaxLength(1000)]
            public string Description { get; set; }
            [Required]
            [MaxLength(20)] //标示为 字符串长度最大30
            public string Creator { get; set; }
            [Required]
            public DateTime CreateDateTime { get; set; }
            public string LastModifier { get; set; }
            public DateTime? LastModifiedDateTime { get; set; }
        }
    }

     

    看吧,数据注解(DataAnnotations ),就是旧技术换一个叫法而已。没有什么大不了。其他的就靠大家去摸索了。

    二 . Fluent API  查了一下百度翻译,“流畅的API” ,我不知道这个翻译贴不贴不切,我就以我使用Fluent API 经验说说,Fluent API 比 数据注解好的地方。

        1. 大家再看一眼上面代码,是不是感觉有点不纯净了,本来一个干干净净的类,搞得乱乱的。感觉有点恶心。

        2. 这一点可能要后面我贴出代码,分享源代码才理解,不过使用过EntityFramework Fluent API 的应该能够理解到,配置和类分离,职责更加单一。

       3. 配置和类分离,扩展性,灵活性就会更好,大家多知道,EntityFramework 不仅支持Sql Server,支持Oracle,MySql,Sqlite 等这些流行数据库,每种产品配置也许都有细微差别,如果以 DataAnnotations 方式实作,那我岂不是要重新新增模型,一样的表设计,为什么要加呢? 只有配置不同才要加啊! 

      4. 做技术架构,这种方式封装也比较好,怎么好大家如果是做架构的话,两种方式都用一下,感受一下。

    废话不多说了,直接贴出实现 Fluent API 的流程,以及代码。

    1. 创建数据库“EntityFrameworkSample”

    2. 在数据库“EntityFrameworkSample”中,加表“Sample_Order”,然后向表中新增所需要的字段。

    3. 新建解决方案 “EntityFrameworkSample” 

    4. 在解决方案中 新增“EntityFrameworkSample.DbContext” (配置最终使用地方),“EntityFrameworkSample.Models”(纯净数据Model),“EntityFrameworkSample.Mappings” (映射配置)三个类库项目

    5. 在“EntityFrameworkSample.DbContext” ,“EntityFrameworkSample.Mappings”  项目中,通过NuGet 安装EntityFramework 最新版本。

    6. 在 “EntityFrameworkSample.DbContext” 项目中,新增“EntityFrameworkSampleDbContext” DbContext 类,

        在“EntityFrameworkSample.Models” 项目中,新增“OrderModel” Model类,

        在“EntityFrameworkSample.Mappings”项目中,新增“OrderMap” 映射配置类。

    三个项目 代码图 和引用关系如下图

    三个类的代码分别如下

    EntityFrameworkSampleDbContextusing System.Data.Entity;using EntityFrameworkSample.Mappings;

    using EntityFrameworkSample.Models;
    
    namespace EntityFrameworkSample.DbContext
    {
        public class EntityFrameworkSampleDbContext:System.Data.Entity.DbContext
        {
            public EntityFrameworkSampleDbContext()
                : base("EntityFrameworkSampleConnection")
            {
            }

    public DbSet<OrderModel> orders { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new OrderMap()); base.OnModelCreating(modelBuilder); } } }

    OrderModel

    using System;
    
    namespace EntityFrameworkSample.Models
    {
        public class OrderModel
        {     
            public Guid OrderGuid { get; set; }
            public string OrderNo { get; set; }
            public string OrderCreator { get; set; }
            public DateTime OrderDateTime { get; set; }
            public string OrderStatus { get; set; }
            public string Description { get; set; }
            public string Creator { get; set; }
            public DateTime CreateDateTime { get; set; }
            public string LastModifier { get; set; }
            public DateTime LastModifiedDateTime { get; set; }
        }
    }

    OrderMap

    using System.ComponentModel.DataAnnotations.Schema;
    using System.Data.Entity.ModelConfiguration;
    using EntityFrameworkSample.Models;
    
    namespace EntityFrameworkSample.Mappings
    {
        public class OrderMap : EntityTypeConfiguration<OrderModel>
        {
            public OrderMap()
            {
                this.HasKey(m => m.OrderGuid);
    
                this.Property(m => m.OrderGuid)
                    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    
                this.Property(m => m.OrderNo)
                    .IsRequired()
                    .HasMaxLength(30);
    
                this.Property(m => m.OrderCreator)
                    .IsRequired()
                    .HasMaxLength(20);
    
                this.Property(m => m.OrderStatus)
                    .IsRequired()
                    .HasMaxLength(30);
    
                this.Property(m => m.Description)
                    .HasMaxLength(1000);
    
                this.Property(m => m.Creator)
                    .IsRequired()
                    .HasMaxLength(20);
    
                this.Property(m => m.LastModifier)
                 .HasMaxLength(15)
                 .HasMaxLength(20);
    
                this.ToTable("Sample_Order");
    
                this.Property(m => m.OrderGuid).HasColumnName("OrderGuid");
                this.Property(m => m.OrderNo).HasColumnName("OrderNo");
                this.Property(m => m.OrderCreator).HasColumnName("OrderCreator");
                this.Property(m => m.OrderDateTime).HasColumnName("OrderDateTime");
                this.Property(m => m.OrderStatus).HasColumnName("OrderStatus");
                this.Property(m => m.Description).HasColumnName("Description");
                this.Property(m => m.Creator).HasColumnName("Creator");
                this.Property(m => m.CreateDateTime).HasColumnName("CreateDateTime");
                this.Property(m => m.LastModifier).HasColumnName("LastModifier");
                this.Property(m => m.LastModifiedDateTime).HasColumnName("LastModifiedDateTime");
            }
        }
    }

    至此解决方案此阶段所有代码就完成了。

     大概讲一下一些注意点。

    1. EntityFrameworkSampleDbContext 必须要继承 DbContext,并重写OnModelCreating方法,来完成映射.

    2. OrderMap 必须继承EntityTypeConfiguration<>泛型类,泛型类型 OrderModel,大概告诉Map映射的是OrderModel。

    好了,这篇内容结束了,不足的地方,我没有列出Fluent API 所有api,主要是表与表的关系是如何映射的,这些希望读者,能够自己去摸索,篇幅有限,

    还有就是DbContext 我也没有在这篇详细介绍,会在真正讲到DbContext那篇在详细跟大家介绍。

    这篇还增加一篇续篇吧,第三篇:Entity Framework CodeFirst & Model 映射 续篇 EntityFramework Power Tools 工具使用

    这篇的源代码:http://pan.baidu.com/s/1gftuzuF

     

  • 相关阅读:
    和老外交流最常用1000句口语 (一)
    flash自定义右键菜单
    和老外交流最常用1000句口语 (二)
    EBS默认的登录账户和密码
    实例13. 库存补充操作——最小最大计划(MinMax Planning)
    EBS R12常用数据表
    Oracle 软件的行业划分 和 Oracle 公司内部职业划分
    在Org Parameter设置Subinventory Account
    物流(Logistics)的概念
    实例12. 库存补充操作——看板补充(Kanban Replenishment)
  • 原文地址:https://www.cnblogs.com/davidzhou/p/5357308.html
Copyright © 2011-2022 走看看