美文网首页.Netcore
efcore系列一 efcore执行的基本流程

efcore系列一 efcore执行的基本流程

作者: smilekop | 来源:发表于2019-08-07 21:49 被阅读0次

    最近终于闲下来了,有点时间来写一下使用efcore过程中遇到的的一些细节问题。这个系列会从基础开始,可能会比较啰嗦(~ ̄▽ ̄)~。

    开发环境 VS2019 .NET Core2.2 mysql8.0

    会用到的包,列一下:

    Microsoft.EntityFrameworkCore
    Microsoft.EntityFrameworkCore.Tools
    Pomelo.EntityFrameworkCore.MySql
    Microsoft.Extensions.Configuration
    Microsoft.Extensions.Configuration.Json
    

    为什么不用官方的包MySql.Data.EntityFrameworkCore,我只能说,从2018年4月份开始使用corefirst的体验来看,官方的驱动做的实在是烂,对数据迁移不够友好,至2019年群里的小伙伴还在吐槽不支持GUID(未核实)。

    接下来是正文:

    1. 新建一个控制台项目EFCoreFirst,做一下简单的演示就不用web项目了。

    添加一个appsetting.json配置文件,属性设置始终复制

    {
      "ConnectionString": "server=127.0.0.1;port=3306;database=efcore_demo;uid=sa;pwd=123456;"
    }
    

    2. 安装包

    package.PNG

    3. 添加实体

    ef core是关于访问数据库的,但是这个数据库是从哪里来的呢?ef core提供了两个选项:通过ef core创建它,称为code first,或者手动创建数据库,称为database first。

    这个例子中会使用codefirst创建一个简单的数据库,包含两张表:Products 包含产品信息,Order 包含订单信息


    table.PNG

    现在可以开始编写efcore相关的代码了,在创建任何数据库访问代码之前,需要编写两个基本部分:
    3.1 由ef core映射到数据库中表的类
    3.2 应用程序的DbContext,用于配置和访问数据库的类

    products类:

    [Table("product")]
        public class Products
        {
            /// <summary>
            /// key显示将ProductId设为主键,但是我们已经使用了efcore命名约定,它告诉efcore属性ProductId是主键,所以可以省略
            /// </summary>
            [Key]
            public virtual int ProductId { get; set; }
    
            /// <summary>
            /// 产品名称
            /// </summary>
            [StringLength(50)]
            public virtual string Name { get; set; }
    
            /// <summary>
            /// 产品数量
            /// </summary>
            public virtual int Count { get; set; }
    
            /// <summary>
            /// 价格
            /// </summary>
            public virtual Decimal Price { get; set; }
    
            /// <summary>
            /// 外键
            /// </summary>
            public virtual int OrderId { get; set; }
    
            /// <summary>
            /// Order属性是efcore导航属性。efcore在save中使用这个来查看products否附加了order类,如果附加了order类,它将设置外键orderId
            /// 这里有一个新的命名约定 efcore知道OrderId是一个外键,当它鱼Order类的主键名称一致
            /// </summary>
            public virtual Order Order { get; set; }
        }
    

    Order类:

    [Table("order")]
        public class Order
        {
            [Key]
            public virtual int OrderId { get; set; }
            
            /// <summary>
            /// 订单编号
            /// </summary>
            [StringLength(25)]
            public virtual string OrderCode { get; set; }
    
            /// <summary>
            /// 买家名称
            /// </summary>
            [StringLength(25)]
            public virtual string Buyer { get; set; }
        }
    

    4. 添加数据库上下文

    public class AppDbContext:DbContext
        {
            private static string ConnStr;
    
            static AppDbContext()
            {
                var builder = new ConfigurationBuilder();
                builder.AddJsonFile("appsetting.json");
                var config = builder.Build();
                ConnStr = config["ConnectionString"];
            }
    
            protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
            {
                optionsBuilder.UseMySql(ConnStr);
            }
    
            
            public DbSet<Products> Products { get; set; }
        }
    

    5. 添加迁移文件,执行迁移

    add-migration.PNG

    查看生成的数据库表,可以看到表product表按预期生成


    product.PNG

    efcore生成迁移文件的过程,以products为例子:
    5.1 在AppDbContext中查找所有DbSet<T> 属性,这里找到了Products类,获取到了表名称(从Table特性中,未设置则默认为类名)
    5.2 查看DbSet<T>中所有类T(这里是Products类),并查看其属性以计算列名、类型等。它还查找类和或属性上提供额外建模信息的特殊属性如StringLength特性
    5.3 查找DbSet<T>类所引用的任何类(Products类中的Order)。在这个例子中,Products类引用了Order类,所以efcore也会扫描它。它对Order类的属性执行与步骤2中对Products相同的操作。
    5.4 efcore在应用程序的DbContext中运行OnModelCreating方法,这里我们未重写这个方法,该方法可以添加一些配置。
    5.5 efcore根据以上步骤收集的所有信息创建数据库的内部模型,生成迁移文件。

    6. 尝试操作数据

    public class Program
        {
            static void Main(string[] args)
            {
                AddProduct();
                var product = GetSingleProduct();
                Console.WriteLine($"{product?.ProductId}--{product?.Name}");
    
                Console.ReadLine();
    
            }
    
            public static void AddProduct()
            {
                using (var dbContext=new AppDbContext())
                {
                    var product = new Products()
                    {
                        Name = "apple",
                        Price = 3.0M,
                        Count = 10,
                        Order = new Order {
                            OrderCode = "0001",
                            Buyer="xiaoming"
                        }
                    };
    
                    dbContext.Add<Products>(product);
                    dbContext.SaveChanges();
                }
            }
    
            public static Products GetSingleProduct()
            {
                using (var dbContext = new AppDbContext())
                {
                    var product = dbContext.Products.FirstOrDefault();
                    return product;
                }
            }
        }
    

    操作成功:


    insert.PNG

    相关文章

      网友评论

        本文标题:efcore系列一 efcore执行的基本流程

        本文链接:https://www.haomeiwen.com/subject/dhvadctx.html