EFCORE 延迟加载和EF数据模型创建
先建第一个商店表
/// <summary> /// 店铺表 /// </summary> public class Sys_Shop { /// <summary> /// 主键 /// </summary> [Key] public int Id { get; set; } /// <summary> /// 店铺名称 /// </summary> public string Name { get; set; } /// <summary> /// 店铺logo /// </summary> public string Images { get; set; } /// <summary> /// 店铺简介 /// </summary> public string Synopsis { get; set; } /// <summary> /// 删除标识 /// </summary> public bool Delete { get; set; } /// <summary> /// 账号 /// </summary> public virtual ICollection<Sys_Account> Sys_Accounts { get; set; } }
然后建用户表
/// <summary> /// 账号表 /// </summary> public class Sys_Account { /// <summary> /// 主键 /// </summary> public int Id { get; set; } /// <summary> /// 账号 /// </summary> public string Account { get; set; } /// <summary> /// 密码 /// </summary> public string Password { get; set; } /// <summary> /// 手机号 /// </summary> public string Phone { get; set; } /// <summary> /// 头像 /// </summary> public string Image { get; set; } /// <summary> /// 删除标识 /// </summary> public bool Delete { get; set; } /// <summary> /// 创建时间 /// </summary> public DateTime CareateTime { get; set; }
/// <summary>
/// Sys_Shop 表关联字段
/// </summary> public int Fid { get; set; } /// <summary> /// 使用 [ForeignKey("Fid")]设置对应外键 批注[ForeignKey]
可以放置在关系中的任一导航属性上。 它不需要转到依赖实体类中的导航属性。 /// </summary> [ForeignKey("Fid")] public virtual Sys_Shop Sys_Shops { get; set; } }
术语的定义
有许多用于描述关系的术语
-
依赖实体: 这是包含外键属性的实体。 有时称为关系的"子级"。
-
主体实体: 这是包含主键/备用键属性的实体。 有时称为关系的"父级"。
-
主体密钥: 唯一标识主体实体的属性。 这可能是主键或备用密钥。
-
外键: 依赖实体中用于存储相关实体的主体键值的属性。
-
导航属性: 在引用相关实体的主体和/或依赖实体上定义的属性。
-
集合导航属性: 一个导航属性,其中包含对许多相关实体的引用。
-
引用导航属性: 保存对单个相关实体的引用的导航属性。
-
反向导航属性: 讨论特定导航属性时,此术语是指关系另一端上的导航属性。
-
-
自引用关系: 依赖实体类型与主体实体类型相同的关系。
完全定义的关系
关系的最常见模式是在关系的两端定义导航属性,在依赖实体类中定义外键属性。
-
如果在两种类型之间找到了一对导航属性,则它们将被配置为相同关系的反向导航属性。
-
如果依赖实体包含一个名称与以下模式之一匹配的属性,则它将配置为外键:
<navigation property name><principal key property name> 导航属性名称主要密钥属性名称;
<navigation property name>Id 导航属性名称和ID
<principal entity name><principal key property name> 主体单位名称主要关键财产名称
<principal entity name>Id 主要实体名称Id
这是官方例子
public class Blog { public int BlogId { get; set; } public string Url { get; set; } public List<Post> Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public int BlogId { get; set; } // 主表Id public Blog Blog { get; set; } //主表名称对应 }
1.排除字段映射使用 [
protected override void OnModelCreating(ModelBuilder modelBuilder) {
//设置构成此实体类型的主键的属性。 modelBuilder.Entity<Sys_Account>().HasKey(c => new { c.CareateTime, c.Id }); base.OnModelCreating(modelBuilder); }
开启efcode延时加载
1.使用延迟加载的最简单方式是通过安装 Microsoft.EntityFrameworkCore.Proxies
2.启用懒加载
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseLazyLoadingProxies()
.UseSqlServer();
}
3.EF Core 接着会为可重写的任何导航属性(即,必须是 virtual
且在可被继承的类上)启用延迟加载。 例如,在以下实体中,Post.Blog
和 Blog.Posts
导航属性将被延迟加载。
public class Blog { public int Id { get; set; } public string Name { get; set; } public virtual ICollection<Post> Posts { get; set; } } public class Post { public int Id { get; set; } public string Title { get; set; } public string Content { get; set; } public virtual Blog Blog { get; set; } }
使用示例
var model = _account.GetMany(m => m.Account == dto.Account && m.Password == dto.Password).FirstOrDefault();
_account.GetMany返回的是 IQueryable<T>
var roles = model.Sys_Account_Role.ToList();
延迟加载官方文档地址
https://docs.microsoft.com/zh-cn/ef/core/querying/related-data/lazy
主键外键官方文档地址
https://docs.microsoft.com/zh-cn/ef/core/modeling/keys?tabs=data-annotations