Entity Framework (EF) Core工具创建一对多和多对多的关系
一、 EntirtyFramework(EF)简介
EntirtyFramework框架是一个轻量级的可扩展版本的流行实体框架数据访问技术,微软官方提供的ORM工具让开发人员节省数据库访问的代码时间,将更多的时间放到业务逻辑层代码上。EF提供变更跟踪、唯一性约束、惰性加载、查询事物等。开发人员使用Linq语言,对数据库操作如同操作Object对象一样省事。
EF有三种使用场景,1. 从数据库生成Class(DB First),2.由实体类生成数据库表结构(Code First),3. 通过数据库可视化设计器设计数据库,同时生成实体类(Model First)。
EF架构如下:
EDM (实体数据模型):EDM包括三个模型,概念模型、 映射和存储模型。
概念模型 ︰ 概念模型包含模型类和它们之间的关系。独立于数据库表的设计。
存储模型 ︰ 存储模型是数据库设计模型,包括表、 视图、 存储的过程和他们的关系和键。
映射 ︰ 映射包含有关如何将概念模型映射到存储模型的信息。
LINQ to Entities ︰ LINQ to Entities 是一种用于编写针对对象模型的查询的查询语言。它返回在概念模型中定义的实体。
Entity SQL: Entity SQL 是另一种炉类似于L2E的言语,但相给L2E要复杂的多,所以开发人员不得不单独学习它。
Object Services(对象服务):是数据库的访问入口,负责数据具体化,从客户端实体数据到数据库记录以及从数据库记录和实体数据的转换。
Entity Client Data Provider:主要职责是将L2E或Entity Sql转换成数据库可以识别的Sql查询语句,它使用Ado.net通信向数据库发送数据可获取数据。
ADO.Net Data Provider:使用标准的Ado.net与数据库通信。
二、EntirtyFrameworkCore(EF Core)
Entity Framework Core (EF Core) 是在 2016 年首次发布的 EF6 的完全重写。 它附带于 Nuget 包中,是 Microsoft.EntityFrameworkCore 的主要组成部分。 EF Core 是一种跨平台产品,可以在 .NET Core 或 .NET Framework 上运行。EF Core 提供了在 EF6 中不会实现的新功能(如备选键、批量更新以及 LINQ 查询中的混合客户端/数据库评估。但由于它是一个新代码库,所以会缺少一些 EF6 中的功能。
EFCore与之前的EF基本类似,区别在于配置的时候有一些差异;支持DB First和Model First,广泛使用的Code First模式;EF Core2.1开始支持Lazy loading。
EFCore的数据库访问技术使用之前请先安装Microsoft.EntityFrameworkCore包
三、EF Core使用DB First
数据库优先(DB First),编码步骤如下:
1、新建数据库
2、对模型实施反向工程
Scaffold-DbContext [-Connection] <String> [-Provider] <String> [-OutputDir <String>] [-Context <String>]
[-Schemas <String>] [-Tables <String>] [-DataAnnotations] [ -Force] [-Project <String>]
[-StartupProject <String>] [-Environment <String>] [<CommonParameters>]
3、在项目中配置数据库连接字符串。
四、EF Core使用Code First
编码优先(Code First),执行步骤如下:
1、新建模型类
2、新建DBContext
3、在项目中配置数据库连接字符串
4、执行如下命令(数据库迁移): Add-Migration [类名], Update-Database
数据表级联,这里主要说一下级联删除
1、外键属性可为NULL的级联删除时外键属性直接设置为 null即可
2、外键属性不可为NULL级联删除时会引发异常,需要设置删除行为 DeleteBehavior ,DeleteBehavior 的类型如下表所示
数据加载是需要重点掌握的,EF的关联实体加载有三种方式:Lazy Loading,Eager Loading,Explicit Loading,其中Lazy Loading和Explicit Loading都是延迟加载。
(一)Lazy Loading(惰性加载)使用的是动态代理,默认情况下,如果POCO类满足以下两个条件,EF就使用Lazy Loading:
POCO类是Public且不为Sealed。导航属性标记为Virtual。
关闭Lazy Loading,可以将LazyLoadingEnabled设为false,如果导航属性没有标记为virtual,Lazy Loading也是不起作用的。
/// <summary>
/// 用户信息表
/// </summary>
public class User
{
/// <summary>
/// 用户ID
/// </summary>
//[Key]
//[DatabaseGenerated(DatabaseGeneratedOption.Identity)] //设置自增
public int UserId { get; set; }
/// <summary>
/// 用户编码
/// </summary>
public string UserNo { get; set; }
/// <summary>
/// 用户名称
/// </summary>
public string UserName { get; set; }
/// <summary>
/// 用户电话
/// </summary>
public string TelPhone { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Remark { get; set; }
public virtual Orginazation Org { get; set; }
public virtual ICollection<UserAndRole> Roles { get; set; }
}
User实体类
/// <summary>
/// 角色信息表
/// </summary>
public class Role
{
/// <summary>
/// 角色ID
/// </summary>
//[Key]
//[DatabaseGenerated(DatabaseGeneratedOption.Identity)] //设置自增
public int RoleID { get; set; }
/// <summary>
/// 角色编码
/// </summary>
public string RoleNO { get; set; }
/// <summary>
/// 角色名称
/// </summary>
public string RoleName { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Remark { get; set; }
public virtual ICollection<UserAndRole> Users { get; set; }
}
Role实体类
/// <summary>
/// 部门信息表
/// </summary>
public class Orginazation
{
//private readonly ILazyLoader _lazyLoader; //public Orginazation(ILazyLoader lazyLoader)
//{
// _lazyLoader = lazyLoader;
//} /// <summary>
/// 部门ID
/// </summary>
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] //设置自增
public int OrgId { get; set; }
/// <summary>
/// 部门编码
/// </summary>
public string OrgNO { get; set; }
/// <summary>
/// 部门名称
/// </summary>
public string OrgName { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Remark { get; set; }
public virtual ICollection<User> Users { get; set; }
}
Orginazation实体类
在.net Core2.0及以上版本中使用惰性加载需要引用惰性加载代理包,EF Core一般情况下使用惰性加载,因此为了避免报循环引用的异常需要设置ReferenceLoopHandling为Ignore
Install-package Microsoft.EntityFrameworkCore.Proxies
Startup.cs文件显示使用惰性加载
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
}); services.AddDbContext<CodeFirstContext>(options =>
{
//注入数据库
options.UseSqlServer(Configuration.GetConnectionString("SqlServerConnStr")).ToString();
//打开延迟加载代理的创建。
options.UseLazyLoadingProxies();
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1).AddJsonOptions(options =>
{
//由于使用了惰性加载,因此需要设置此参数避免报循坏引用的异常
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
}
Startup.cs
public class HomeController : Controller
{
private readonly CodeFirstContext _dbContext;
public IConfiguration Configuration { get; }
string conn = string.Empty;
public HomeController(CodeFirstContext _context)
{
_dbContext = _context;
}
public IActionResult Index()
{
Role role = new Role
{
RoleNO = "",
RoleName = "管理员角色",
Remark = "所有权限"
};
Orginazation org = new Orginazation
{
OrgNO = "",
OrgName = "总公司",
Remark = "部门根节点"
};
User user = new User
{
UserNo = "admin",
UserName = "管理员",
Remark = "系统管理员",
TelPhone="",
Org = org
};
UserAndRole userAndRoleModel = new UserAndRole
{
Role = role,
User = user,
RoleID = role.RoleID,
UserId = user.UserId
};
user.Roles.Add(userAndRoleModel);
role.Users.Add(userAndRoleModel);
_dbContext.Roles.Add(role);
_dbContext.Orginazations.Add(org);
_dbContext.Users.Add(user);
_dbContext.UserAndRoles.Add(userAndRoleModel); _dbContext.SaveChanges(); //延迟加载
var orgs = _dbContext.Orginazations;
foreach (var userModel in orgs.FirstOrDefault().Users)
{
//删除部门用户
_dbContext.Users.Remove(userModel);
}
_dbContext.SaveChanges();
return View();
} public IActionResult About()
{
_dbContext.Roles.Add(new Role
{
RoleNO = "role1",
RoleName = "RoleName1",
Remark = "Remark1"
}); //删除用户,对应头像表里的数据也会被删除
var user = _dbContext.Users.First();
_dbContext.Users.Remove(user);
_dbContext.SaveChanges(); ViewData["Message"] = "Your application description page."; return View();
} public IActionResult Contact()
{
ViewData["Message"] = "Your contact page."; return View();
} public IActionResult Privacy()
{
return View();
} [ResponseCache(Duration = , Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
HomeController
/// <summary>
/// Code First编码上下文
/// </summary>
public class CodeFirstContext : DbContext
{
public CodeFirstContext(DbContextOptions<CodeFirstContext> conn)
: base(conn)
{
}
/// <summary>
/// 映射用户信息表
/// </summary>
public virtual DbSet<User> Users { get; set; }
/// <summary>
/// 映射部门信息表
/// </summary>
public virtual DbSet<Orginazation> Orginazations { get; set; }
/// <summary>
/// 映射角色信息表
/// </summary>
public virtual DbSet<Role> Roles { get; set; }
/// <summary>
/// 用户角色信息表
/// </summary>
public virtual DbSet<UserAndRole> UserAndRoles { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//用户
modelBuilder.Entity<User>(entity =>
{
entity.ToTable("User");
entity.Property(e => e.UserName).IsRequired().HasMaxLength();
entity.Property(e => e.UserNo).IsRequired().HasMaxLength();
entity.Property(e => e.TelPhone).HasMaxLength();
entity.Property(e => e.Remark).HasMaxLength();
entity.HasOne(u => u.Org).WithMany(r => r.Users).OnDelete(DeleteBehavior.SetNull); }); //角色
modelBuilder.Entity<Role>(entity =>
{
entity.ToTable("Role");
entity.Property(e => e.RoleName).IsRequired().HasMaxLength();
entity.Property(e => e.RoleNO).IsRequired().HasMaxLength();
entity.Property(e => e.Remark).HasMaxLength();
}); //部门信息
modelBuilder.Entity<Orginazation>(entity =>
{
entity.ToTable("Orginazation");
entity.Property(e => e.OrgNO).IsRequired().HasMaxLength();
entity.Property(e => e.OrgName).IsRequired().HasMaxLength();
entity.Property(e => e.Remark).HasMaxLength();
//多个用户对应一个部门
entity.HasMany(u => u.Users).WithOne(r => r.Org).OnDelete(DeleteBehavior.SetNull);
}); //用户角色信息表
modelBuilder.Entity<UserAndRole>(entity =>
{
entity.ToTable("UserAndRole");
entity.HasKey(ua => new { ua.RoleID, ua.UserId });
});
modelBuilder.Entity<UserAndRole>(entity =>
{
entity.ToTable("UserAndRole");
entity.HasOne(u => u.Role).WithMany(r => r.Users);
});
modelBuilder.Entity<UserAndRole>(entity =>
{
entity.ToTable("UserAndRole");
entity.HasOne(u => u.User).WithMany(r => r.Roles);
});
}
}
CodeFirstContext数据库上下文类
执行数据库迁移命令Add-Migration init22222结果如下:
更新数据库Update-Database,生成数据库表结果如下:
至此、Code First主要步骤完成了,通过Code First正确创建了表之间一对多和多对多的关系,本实例中User和Role是多对多的关系,User和Orginazation是多对一的关系,
(二)Eager Loading(预加载)使用Include方法关联预先加载的实体。在这里就不举例说明了。
(三)Explicit Loading(直接加载)使用Entry方法,对于集合使用Collection,单个实体则使用Reference。在这里就不举例说明了。
以上是我对Entity Framework Core的总结和使用,欢迎纠错!!!
Entity Framework (EF) Core工具创建一对多和多对多的关系的更多相关文章
- ASP.NET Core 开发 - Entity Framework (EF) Core
EF Core 1.0 Database First http://www.cnblogs.com/linezero/p/EFCoreDBFirst.html ASP.NET Core 开发 - En ...
- Entity Framework (EF) Core学习笔记 1
1. Entity Framework (EF) Core 是轻量化.可扩展.开源和跨平台的数据访问技术,它还是一 种对象关系映射器 (ORM),它使 .NET 开发人员能够使用面向对象的思想处理数据 ...
- ASP.NET Core 开发-Entity Framework (EF) Core 1.0 Database First
ASP.NET Core 开发-Entity Framework Core 1.0 Database First,ASP.NET Core 1.0 EF Core操作数据库. Entity Frame ...
- 【极力分享】[C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例【转载自https://segmentfault.com/a/1190000004152660】
[C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例 本文我们来学习一下在Entity Framework中使用Cont ...
- 在Entity Framework 中用 Code First 创建新的数据库
在Entity Framework 中用 Code First 创建新的数据库 (原文链接) 本文将逐步介绍怎样用Code First 创建新数据库,使用在代码中定义类和API中提供的特性(Attri ...
- Visual Studio Entity Framework (EF) 生成SQL 代码 性能查询
Visual Studio Entity Framework (EF) 生成SQL 代码 性能查询 SQL 中,有SQL Server Profiler可以用来查询性能以及查看外部调用的SQL ...
- [转]Using Entity Framework (EF) Code-First Migrations in nopCommerce for Fast Customizations
本文转自:https://www.pronopcommerce.com/using-entity-framework-ef-code-first-migrations-in-nopcommerce-f ...
- ADO.NET Entity Framework(EF)
ylbtech-Miscellaneos: ADO.NET Entity Framework(EF) A,返回顶部 1, ADO.NET Entity Framework 是微软以 ADO.NET 为 ...
- ORM之Entity Framework(EF)
ORM之Entity Framework(EF) 一.下载安装: nuget 搜索Entity Framework安装 EntityFramework.Extension是个扩展库根据需要安装 二.使 ...
随机推荐
- 并发的核心:CAS 是什么?Java8是如何优化 CAS 的?
大家可能都听说说 Java 中的并发包,如果想要读懂 Java 中的并发包,其核心就是要先读懂 CAS 机制,因为 CAS 可以说是并发包的底层实现原理. 今天就带大家读懂 CAS 是如何保证操作的原 ...
- MIPCache 域名升级
一.MIPCache URL 是什么 举个例子,MIP 官网的 URL 为: https://www.mipengine.org 对应的 MIPCache 的 URL 为: https://mipca ...
- 聊聊真实的 Android TV 开发技术栈
智能电视越来越普及了,华为说四月发布智能电视跳票了,一加也说今后要布局智能电视,在智能电视方向,小米已经算是先驱了.但是还有不少开发把智能电视简单的理解成手机屏幕的放大,其实这两者并不一样. 一.序 ...
- subprocess实时获取结果和捕获错误
需要调用命令行来执行某些命令,主要是用 subprocess 实时获取结果和捕获错误,发现subprocess的很多坑. subprocess 普通获取结果方式,其需要命令完全执行才能返回结果: im ...
- cannot be cast to java.lang.Comparable
Exception in thread "main" java.lang.ClassCastException: com.myradio.People cannot be cast ...
- flutter初体验
flutter初体验 和flutter斗争了两个周末,基本弄清楚了这个玩意的布局和一些常用组件了. 在flutter里面,所有东西都是组件Widget.我们像拼接积木一样拼接Widget,拼接的关键词 ...
- 一个简单的cmake例子
一个简单的cmake例子CMakeLists.txt,生成动态库文件,可以指定发布目录. 尚不支持: 1.交叉编译环境配置 2.添加依赖库 #在当前目录新建一个build目录,然后cd build ...
- How to resolve CSRF protection error while adding service through Ambari api
Short Description: This article will describe on how to disable CSRF protection in Ambari. Article A ...
- Python学习日记(一):拜见小主——Python
近日学习Python,特将学习过程及一点心得记录于此. 由于之前做过一个Java爬虫的项目,虽然很长时间没有碰过爬虫,但是小郭同学有一颗不死的爬虫心,哈哈.最近在互联网上找一些电影的时候,有很多电影只 ...
- webgl自学笔记——深度监测与混合
这一章中关于webgl中颜色的使用我们将深入研究.我们将从研究颜色在webgl和essl中如何被组装和获取开始.然后我们讨论在物体.光照和场景中颜色的使用.这之后我们将看到当一个物体在另一个物体前面是 ...