EF Core杂记

提示:前面的EF Core例子中我们会有很多疑问,比如为什么我们只建立实体类并进行了一些乱七八糟的配置,数据库中就有了对应表?那些表的名字和字段是怎么指定的?在哪指定的?


一,EF Core的实体类配置

EF Core 作为一个ORM框架,它完成了实体类和数据库中表的映射,这里面有着怎样的约定,有着怎样的默认配置?

1.约定大于配置

这个概念的提出我并不意外,之前学Java时,Springboot的核心理念就是约定大于配置,大概意思就是我们会准备一套默认的配置,这是一个约定,当我们不去修改的时候,就会默认,这样会减少很多不必要的简单配置,当然一些需要根据具体业务场景才能决定,这些会有对应的接口提供自定义配置。
在EF Core中,也采用了“约定大于配置”的原则,EF Core会默认按照约定根据实体类以及DbContext的定义类实现和数据库表的映射配置,除非我们显式指定了配置规则,比如上一篇中的ToTable("T_Books")

EF Core中的默认的规则约定有很多,这里只列出一些主要的约定规则

  1. 数据库表名采用上下文类中对应的DbSet的属性名
  2. 数据库表列的名字采用实体类属性的名字,列的数据类型采用和实体属性类型兼容的类型
  3. 数据库表列的可空性取决于对应实体类属性的可空性。EF Core6 中支持C#中的可空引用类型
  4. 名字为Id的属性为主键,如果主键为short,int或者long类型,则主键默认采用自动增长类型的列

2.EF Core的大概执行过程

C#—>EF Core核心–>AST—> SQL Server EF Core provider —> SQL Server ADO.NET provider

上面的路线大概是我们进行一个检查的查询时EF Core所执行的

C#代表的就是我们编写的查询代码

                Article article = context.Articles.Include(a => a.comments).Single(a => a.Id == 1);
                Console.WriteLine(article.Id);
                Console.WriteLine(article.Title);
                foreach(Comment com in article.comments)
                {
                    Console.WriteLine(com.Id+","+com.Message);
                }

EF Core核心指的是我们EF Core框架,它把C#代码翻译为AST(抽象语法树),然后把AST,抽象语法树翻译为SQL语句,然后由SQL Server EF Core provider来把SQL放入到SQL Server ADO.NET provider中,然后由ADO.NET来执行SQL。

说到这里,可能还是会有疑问,这些东西都是啥,ADO.NET是就是SQL语句一个简单封装,地位相当与JAVA中的JDBC,而上面的那些东西都是框架,就比如EF Core这个ORM框架类比为Mybatis等持久层…

一、使用代码查看SQL执行语句

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

  • 标准日志方式
    • 需要安装日志包 Install-Package Microsoft.Extensions.Logging.Console
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EFCoreTest1
{
    class MyDbContext:DbContext
    {
        //使用标准日志
        private static ILoggerFactory loggerFactory = LoggerFactory.Create(b=>b.AddConsole());
        public DbSet<Book> Books { get; set; }
        public DbSet<Person> Persons { get; set; }

        public DbSet<Dog> Dogs { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);
            optionsBuilder.UseSqlServer("Server=.;Database=demo1;Trusted_Connection=True;MultipleActiveResultSets=true;Encrypt=True;TrustServerCertificate=True;");
			//这里使用
            optionsBuilder.UseLoggerFactory(loggerFactory);
            /*optionsBuilder.LogTo(msg =>
            {
                if (!msg.Contains("CommandExecuting")) return;
                Console.WriteLine(msg);
            });*/
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            //从当前程序集中加载所有的IEntityTypeConfiguration
            modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
        }
    }
}

  • 简单日志
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EFCoreTest1
{
    class MyDbContext:DbContext
    {
        //private static ILoggerFactory loggerFactory = LoggerFactory.Create(b=>b.AddConsole());
        public DbSet<Book> Books { get; set; }
        public DbSet<Person> Persons { get; set; }

        public DbSet<Dog> Dogs { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);
            optionsBuilder.UseSqlServer("Server=.;Database=demo1;Trusted_Connection=True;MultipleActiveResultSets=true;Encrypt=True;TrustServerCertificate=True;");

            //optionsBuilder.UseLoggerFactory(loggerFactory);
            
            //简单日志
            optionsBuilder.LogTo(msg =>
            {
                if (!msg.Contains("CommandExecuting")) return;
                Console.WriteLine(msg);
            });
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            //从当前程序集中加载所有的IEntityTypeConfiguration
            modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
        }
    }
}

  • ToQueryString
				IQueryable<Book> books = myDbContext.Books.Where(p => p.AuthorName == "杨中科" && p.Title == "程序员的SQL金典");
				//这里是
                string sql = books.ToQueryString();
                Console.WriteLine("这就是我想要的!" + sql);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

栀梦星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值