.NetCore中EFCore的使用整理(二)-关联表查询

EF常用处理关联加载的方式有3中:延迟加载(Lazy Loading)、贪婪加载 (Eager Loading)以及显示加载。

一、EF Core  1.1

1.当前的版本,还不支持延迟加载(Lazy Loading),不将来是否支持

2.目前支持贪婪加载:使用Include加载 关联表 的数据,这种方式 使用一条Join的 Sql语句进行查询。

3. 贪婪加载的优势在于仅执行1次SQL查询即返回所需要的结果。但使用JOIN查询在数据库记录条数较多时,多条简单的SQL查询往往比一条复杂的JOIN查询效率要好。

Include语句可以在 一次查询中使用多次 :

ctx.Categories
    .Include(c => c.Products)
    .Include(c => c.News);

4.限制加载的方式暂时忽略使用。

二、EF Core 中主外键设置

1.使用数据注释,DataAnnotations模式,这种方式适合Code First或者说手写实体类和自定义主外键 关联。

Menu表

复制代码
[Table("Menu")]
public partial class Menu
{
    [Key]
    public int MenuID { get; set; }
    public string MenuName { get; set; }


    public string LinkUrl { get; set; }
    public DateTime AddTime { get; set; }
    public int SortNumber { get; set; }

    public int ModelID { get; set; }

    [ForeignKey("ModelID")]
    public virtual Model Model { get; set; }
}
View Code
复制代码

Model表

复制代码
[Table("Model")]
public partial class Model
{

    public Model()
    {
        this.Menus = new HashSet<Menu>();
    }

    [Key]
    public int ModelID { get; set; }
    public string ModelName { get; set; }
    public int SortNumber { get; set; }

    public DateTime AddTime { get; set; }

    public virtual ICollection<Menu> Menus { get; set; }

}
View Code
复制代码

上下文类

复制代码
    public class MenuModelContext : DbContext
    {

        public virtual DbSet<Menu> Menus { get; set; }
        public virtual DbSet<Model> Models { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;database=MenuModel;Trusted_Connection=True;");
        }
    }
View Code
复制代码

2.使用Fluent API模式,这种方式,是自动DBFirst自动生成实体层的默认方式

Menu表

复制代码
public partial class Menu
{
    public int MenuId { get; set; }
    public string MenuName { get; set; }
    public string LinkUrl { get; set; }
    public DateTime AddTime { get; set; }
    public int SortNumber { get; set; }
    public int ModelId { get; set; }

    public virtual Model Model { get; set; }
}
View Code
复制代码

Model表

复制代码
public partial class Model
{
    public Model()
    {
        Menu = new HashSet<Menu>();
    }

    public int ModelId { get; set; }
    public string ModelName { get; set; }
    public int SortNumber { get; set; }
    public DateTime AddTime { get; set; }

    public virtual ICollection<Menu> Menu { get; set; }
}
View Code
复制代码

上下文类:

复制代码
public partial class MenuModelContext : DbContext
{
    public virtual DbSet<Menu> Menu { get; set; }
    public virtual DbSet<Model> Model { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;database=MenuModel;Trusted_Connection=True;");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Menu>(entity =>
        {
            entity.Property(e => e.MenuId).HasColumnName("MenuID");

            entity.Property(e => e.AddTime).HasColumnType("datetime");

            entity.Property(e => e.LinkUrl).HasMaxLength(200);

            entity.Property(e => e.MenuName)
                .IsRequired()
                .HasMaxLength(10);

            entity.Property(e => e.ModelId).HasColumnName("ModelID");

            entity.HasOne(d => d.Model)
                .WithMany(p => p.Menu)
                .HasForeignKey(d => d.ModelId)
                .OnDelete(DeleteBehavior.Restrict)
                .HasConstraintName("FK__Menu__ModelID__25869641");
        });

        modelBuilder.Entity<Model>(entity =>
        {
            entity.Property(e => e.ModelId).HasColumnName("ModelID");

            entity.Property(e => e.AddTime).HasColumnType("datetime");

            entity.Property(e => e.ModelName)
                .IsRequired()
                .HasMaxLength(10);
        });
    }
}
View Code
复制代码

三、使用Include 获取关联表数据实例

注 :使用Include 方式获取的数据为对应类型的对象,而不是动态类型Dynamic_xxxx

复制代码
MenuModelContext _Context = new MenuModelContext();
List<Menu> list = _Context.Menus
    .Include(q => q.Model) //手动指定关联表查询,一对一
    .ToList();
foreach (var item in list)
{
    Console.WriteLine(item.MenuName);
    Console.WriteLine(item.Model);
}
复制代码
复制代码
MenuModelContext _Context = new MenuModelContext();
List<Model> list = _Context.Models
    .Include(q => q.Menus) //手动指定关联表查询,一对多
    .ToList();
foreach (var item in list)
{
    Console.WriteLine(item.ModelName);
    Console.WriteLine(item.Menus.Count);
}
复制代码

 

更多 :

.NetCore中EFCore的使用整理

Asp.Net Core MVC控制器和视图之间传值

VS Code搭建.NetCore开发环境(二)

 

Ef core的其他参考:

http://www.cnblogs.com/libingql/p/3381571.html

http://www.infoq.com/cn/news/2016/08/EF-Core-Roadmap

http://blog.csdn.net/ceg6648/article/details/54767133

posted @   天马3798  阅读(19386)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示