跟着杨中科学习(五)EFCore(三)

通过代码查看EFCore自动生成的数据

1.标准日志

//依赖注入的使用方式
public static readonly ILoggerFactory
    
MyLoggerFactory= LoggerFactory.Create(builder =>
{builder.AddConsole();});

optionsBuilder.UseLoggerFactory(MyLoggerFactory);
//普通方式
 class MyDbConnect : DbContext
 {
     private static ILoggerFactory loggerFactory = LoggerFactory.Create(b=>b.AddConsole());//添加到控制台
     public DbSet<Books> Books { get; set; }

     protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
     {
         base.OnConfiguring(optionsBuilder);
         optionsBuilder.UseSqlServer("Server =. ;Database=EFCoreDemo; Trusted_Connection=True;MultipleActiveResultSets = true");
         optionsBuilder.UseLoggerFactory(loggerFactory);//添加日志

     }
     protected override void OnModelCreating(ModelBuilder modelBuilder)
     {
         base.OnModelCreating(modelBuilder);
         //从当前程序集中寻找实现IEntityTypeConfiguration<>接口的类
         modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
     }
 }

2.简单日志

 // optionsBuilder.LogTo()
class MyDbConnect : DbContext
 {
     public DbSet<Books> Books { get; set; }
     protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
     {
         base.OnConfiguring(optionsBuilder);
         optionsBuilder.UseSqlServer("Server =. ;Database=EFCoreDemo; Trusted_Connection=True;MultipleActiveResultSets = true");
         optionsBuilder.LogTo(mes => { Console.WriteLine(mes); });
     }
     protected override void OnModelCreating(ModelBuilder modelBuilder)
     {
         base.OnModelCreating(modelBuilder);
         //从当前程序集中寻找实现IEntityTypeConfiguration<>接口的类
         modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
     }
 }

3.TOQUERYSTRING

EF Core的Where方法返回的是IQueryable类型,
DbSet也实现了IQueryable接口。IQueryable有扩展方
法ToQueryString()可以获得SQL。

只能获取查询操作的

IQueryable<TPerson> persons = ctx. TPersons. Where(p => p. Name. ToLower () == ".BirthDay == DateTime.Now);
string sql = persons. ToQueryString () :

IQueryble和IEumerable的区别与联系

  • IQueryable继承自IEnumerable,这意味着任何IQueryable<T>的实现也提供了IEnumerable<T>接口的功能。
  • 它们都用于遍历集合,但IQueryable提供了更高级的查询功能,特别是与数据库查询相关的功能。
  • 当你需要对本地集合进行简单的遍历时,使用IEnumerable
  • 当你需要构建一个可以被优化并可能在远程数据源(如数据库)上执行的查询时,使用IQueryable

使用规范

  • 写测试性代码,用简单日志;
  • 正式需要记录SQL给审核人
    员或者排查故障,用标准日志;
  • 开发阶段,从繁杂的查询
    操作中立即看到SQL,用ToQueryString()。

EFCore一对多关系配置

EF Core中实体之间关系的配置的套路:

  • 一对多:HasOne( ... ).WithMany( .. );
  • 一对一:HasOne( ... ).WithOne( ... );
  • 多对多:HasMany( ... ).WithMany( ….. );
 class Article
 {
     public int Id { get; set; }
     public string Title { get; set; }
     public string Message { get; set; }
     public List<Comment> Comments { get; set; } = new List<Comment>();
 }
//////////////////////////////////////////////////////////
 class Comment
 {
     public int Id { get; set; }
     public string Message { get; set; }
     public Article article { get; set; }
 }
class ArticleConfig : IEntityTypeConfiguration<Article>
{
    public void Configure(EntityTypeBuilder<Article> builder)
    {
        builder.ToTable("T_Articles");
    }
}
////////////////////////////////////////////////////////
 class CommentConfig : IEntityTypeConfiguration<Comment>
 {
     public void Configure(EntityTypeBuilder<Comment> builder)
     {
         builder.ToTable("T_Comments");
         builder.HasOne<Article>(c => c.article).WithMany(c => c.Comments).IsRequired();//一对多,一个Article对应多个Comments
     }
 }
 private static async Task Main(string[] args)
 {
     using (MyDbConnect connect=new MyDbConnect())
     {
         Article article = new Article();
         article.Title = "Gucgres";
         article.Message = "是真的,是真的";
         Comment comment01 = new Comment { Message = "好" };
         Comment comment02 = new Comment { Message = "差劲" };
         article.Comments.Add(comment01);
         article.Comments.Add(comment02);
         connect.Articles.Add(article);
         connect.SaveChangesAsync();
         Console.ReadKey();
     }
 }

EFCore一对多关系的获取

private static async Task Main(string[] args)
{
    using (MyDbConnect connect=new MyDbConnect())
    {
        //using Microsoft.EntityFrameworkCore;
        Article article = connect.Articles.Include(a=>a.Comments).FirstOrDefault(e=>e.Id==1);
        foreach (var item in article.Comments)
        {
            await Console.Out.WriteLineAsync(item.Message);
        }
        connect.SaveChangesAsync();
        Console.ReadKey();
    }
}

Include()关键字可以关联查询

EFCore额外的外键字段

为什么需要外键属性
1、EF Core会在数据表中建外键列。
2、如果需要获取外键列的值,就需要做关联查询,效
率低。
3、需要一种不需要Join直接获取外键列的值的方式。

解决方法,手动增加外键

 builder.HasOne<Article>(c => c.article).WithMany(c => c.Comments).HasForeignKey(c=>c.TheArticleId).IsRequired();

单向导航属性

从一个属性可以访问到另一种类型的一个实体

class Article
 {
     public int Id { get; set; }
     public string Title { get; set; }
     public string Message { get; set; }
     public List<Comment> Comments { get; set; } = new List<Comment>();
 }
//////////////////////////////////////////////////////////
 class Comment
 {
     public int Id { get; set; }
     public string Message { get; set; }
     public Article article { get; set; }
 }

article和comment加起来就是双向导航属性。

单项导航属性

不设置反向的属性,然后配置的时候
WithMany()不设置参数即可。

class LeaveConfig : IEntityTypeConfiguration<Leave>
{
    public void Configure(EntityTypeBuilder<Leave> builder)
    {
        builder. ToTable("T_Leaves");
        builder. HasOne<User>(1 => 1.Requester). WithMany (). IsRequired ();
    }
}



CommentConfig:

builder.HasOne<Article>(c=>c.Article).WithMany(a=>
a.Comments).IsRequired();

ArticleConfig:

builder.HasMany<Comment>(a=>a.Comments).WithOne(c=>
c.Article).IsRequired();

posted @ 2024-06-11 16:59  想要来杯咖啡吗  阅读(15)  评论(0编辑  收藏  举报