zoukankan      html  css  js  c++  java
  • EFCore中代码优先锲约和数据类型与数据库的对应关系

    1、引言

    EntityFramework Core这个我在这里就不想做相关介绍了,EFCore是netcore中才出现了,它的前身可以说是EF6,下面就对实体中定义的契约与数据库的对应做一个尝试,在实际工作中用了一段时间后现做一个整体的总结。

    因为有时候只管写了实体,没有去在乎数据库中生成的结构是怎样的,开发开发着途中就会出现问题
    

    2、需要安装的包

    我这里仅对Sql Server做示例,至于Mysql、PostgreSQL、Oracle就留给读者带着同样的思路去做尝试。

    1、首先需要安装的包

    • Microsoft.EntityFrameworkCore
    • Microsoft.EntityFrameworkCore.Design
    • Microsoft.EntityFrameworkCore.SqlServer
      2、配置Context
      这些都是很简单的东西,在这就做过多的解释,直接贴出代码。
    • 定义StudyDbContext
    public class StudyDbContext:DbContext
    {
        public StudyDbContext() { }
    
        public StudyDbContext(DbContextOptions<StudyDbContext> options) : base(options){}
    
    
        public DbSet<Users> Users { get; set; }
        /// <summary>
        /// 模型创建的进行时候配置
        /// </summary>
        /// <param name="modelBuilder"></param>
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
        }
    }
    

    注意:Context中又一个重载构造,实际上是在Service中添加Context的时候进行的配置

    • ConfigureServices中添加Context服务
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    
        services.AddDbContext<StudyDbContext>(builder => builder.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    }
    

    附上连接字符串:

    {
      "ConnectionStrings": {
        "DefaultConnection": "Data Source=(localdb)\MSSQLLocalDB;Database=TestEfCore;Trusted_Connection=True;"
      },
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft": "Warning",
          "Microsoft.Hosting.Lifetime": "Information"
        }
      },
      "AllowedHosts": "*"
    }
    

    这里的配置还有很多其他的,参见定义,后面再做其他配置的介绍。
    在这里插入图片描述

    3、锲约与数据库的对应关系

    下面步入今天的正题

    public class Users
    {
        [Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }
        public int Age { get; set; }
    
        [MaxLength(12)]
        public string Name { get; set; }
    
        public Gender Gender { get; set; }
    
        [DataType(DataType.DateTime)]
        public DateTime CreationTime { get; set; }
    
    }
    public enum Gender
    {
        UnKnow,
        Male,
        Female,        
    }
    

    这里定义一个简单的用户,通过上面定义后再加入到Context中去,上面已经贴出了DbSet<Uers>

    3.1、添加模型更改

    Add-Migration <说明>
    
    使用dotnet  ef migration add <说明>  也是可以的
    

    这时候项目会自动编译,要是出现编译不成功的时候是添加不了的。
    在这里插入图片描述

    说明:这里出现了一个警告是因为我安装的包是3.1.3的,而EF Core tools是使用的3.1.2。避免此错误 也是可以将Microsoft.EntityFrameworkCore.Tools 3.1.3添加到项目中去

    3.2、更新数据库

    当添加完成后会自动生成对应的Mirations文件
    在这里插入图片描述
    这里关于文件里面的内容在此文章中就不在多啰嗦了,后面有需要时我会详细介绍。

    使用命令更新数据库

    update-database
    
    使用dotnet  ef migration database update  也是可以的
    

    在这里插入图片描述
    这样就生成了数据库了
    在这里插入图片描述
    到了这里差不多算是EF Core代码优先整个流程就完成了,其实在实际开发中肯定是单独剥离到仓储里面去单独创建MigrationEntityFrameworkCore层。

    有时候可能需要对应的sql脚本文件,可以使用Script-Migration生成一个随机命名的sql文件

    Script-Migration
    
    使用dotnet  ef migrations script  也是可以的
    

    生成的结果。
    在这里插入图片描述

    3.3、对比

    善于观察的童鞋们肯定已经看出了某些对比关系。

    契约 数据库 说明
    [Table(“Users”)] 数据库表名为Users 不指定名称默认为类名称,包括属性一样
    [Key] 主键
    [ForeignKey(“FK_XXX_XXX”)] 外键 实际开发中我基本上没有定义外键,通过导航属性会自动识别外键
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 自增 DatabaseGeneratedOptions说明,None-既不自增也不计算;Identity-自增;Computed-通过计算得到值(这个后面进行讲解)
    [MaxLength(12)] nvarchar(12) 通过设定length数据库自动建立最大长度约束
    [StringLength(200)] nvarchar(200) 通过设定maximumLength数据库自动建立长度约束
    [Column(TypeName=“datetime”)] datetime 指定数据库类型
    [Column(“Love”)] 数据库列明为Love
    [NotMapped] 不映射到数据库
    后面再对这里的契约进行补充说明,这些都是我平时用到的。
    
    数据类型 数据库类型 说明
    枚举 int 当没有设定可空类型的时候数据库中是非空。值类型默认都是非空,要是希望可为空可以使用 ?语法糖或者Nullable
    bool bit mssql中bit其实就是bool类型
    decimal decimal(18,2) decimal类型在生成的时候会有警告;(No type was specified for the decimal column ‘Udecimal’ on entity type ‘Users’. This will cause values to be silently truncated if they do not fit in the default precision and scale. Explicitly specify the SQL server column type that can accommodate all the values using ‘HasColumnType()’)。意思就是说没有指定精度会默认采用精度截取,但是可以采用[Column(TypeName = “decimal(18,4)”)]来结局,这样会用到很多地方,但是这样存在硬编码始终不爽,至于怎么处理读者自行解决
    string nvarchar(MAX)
    int int
    double float
    float real
    uint bigint
    long bigint
    ulong decimal(20)
    Int16 int
    Int32 bigint
    Int64 bigint
    UInt16 int
    UInt32 bigint
    UInt64 decimal(20)
    dynamic 报错 这个类型有过了解的童鞋们应该就知道为什么会报错了,错误 信息:(The property ‘Users.Udynamic’ could not be mapped, because it is of type ‘object’ which is not a supported primitive type or a valid entity type. Either explicitly map this property, or ignore it using the ‘[NotMapped]’ attribute or by using ‘EntityTypeBuilder.Ignore’ in ‘OnModelCreating’)
    肯定还有很多类型的对应,我这里主要写平时中常用的 数据类型
    

    这边文章中就对这么几个做一个简单的介绍,后面详细的做其他讲解,由于最近大多数都在讨论EF Core各种问题,我也就在这针对我实际开发中用到的做一个讲解,希望能够给还不会不明白的带来帮助。

    3.4、Users代码与表结构

    Users表,这里贴出来是便于童鞋们可以自行测试一下。

    public class Users
        {
            [Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
            public int Id { get; set; }
            public int Age { get; set; }
            [MaxLength(12)]
            public string Name { get; set; }
            public Gender Gender { get; set; }
            public bool IsActive { get; set; }
            [DataType(DataType.DateTime)]
            public DateTime CreationTime { get; set; }
            public double Udouble { get; set; }
            public float Ufloat { get; set; }
            public decimal Udecimal { get; set; }
            public uint Uuint { get; set; }
            public long Ulong { get; set; }
            public ulong Uulong { get; set; }
            public Int16 UInt16 { get; set; }
            public Int32 UInt32 { get; set; }
            public Int64 UInt64 { get; set; }
            public UInt16 UuInt16 { get; set; }
            public UInt32 UuInt32 { get; set; }
            public UInt64 UuInt64 { get; set; }      
            public byte Ubyte { get; set; }        
            public char Uchar { get; set; }
        }
        public enum Gender
        {
            UnKnow,
            Male,
            Female,        
        }
    

    表结构展示
    在这里插入图片描述

    4、总结

    本篇文章就逼逼奈奈到这 ,有那点不正确的地方希望能够指出来,写文章有时候还真是 停费事,能够帮助到某些童鞋的话还是有那么一丝欣慰感 ,关注我持续更新相关实战经验。

  • 相关阅读:
    Android笔记——UI开发
    P2P网络借贷系统-核心功能-用户投标-业务解说
    java回调简单实现
    Java面向对象编程(二)
    POJ-1190-生日蛋糕-DFS(深搜)-枚举-多重剪枝
    设计模式笔记——装饰模式
    bbed初体验
    高速理解环境变量
    最短路算法之 Dijkstra算法
    C++课程资源下载问题
  • 原文地址:https://www.cnblogs.com/cqxhl/p/12993260.html
Copyright © 2011-2022 走看看