一、 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实体类

UserAndRole

在.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工具创建一对多和多对多的关系的更多相关文章

  1. 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 ...

  2. Entity Framework (EF) Core学习笔记 1

    1. Entity Framework (EF) Core 是轻量化.可扩展.开源和跨平台的数据访问技术,它还是一 种对象关系映射器 (ORM),它使 .NET 开发人员能够使用面向对象的思想处理数据 ...

  3. 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 ...

  4. 【极力分享】[C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例【转载自https://segmentfault.com/a/1190000004152660】

      [C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例 本文我们来学习一下在Entity Framework中使用Cont ...

  5. 在Entity Framework 中用 Code First 创建新的数据库

    在Entity Framework 中用 Code First 创建新的数据库 (原文链接) 本文将逐步介绍怎样用Code First 创建新数据库,使用在代码中定义类和API中提供的特性(Attri ...

  6. Visual Studio Entity Framework (EF) 生成SQL 代码 性能查询

    Visual Studio Entity Framework (EF) 生成SQL 代码 性能查询     SQL 中,有SQL Server Profiler可以用来查询性能以及查看外部调用的SQL ...

  7. [转]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 ...

  8. ADO.NET Entity Framework(EF)

    ylbtech-Miscellaneos: ADO.NET Entity Framework(EF) A,返回顶部 1, ADO.NET Entity Framework 是微软以 ADO.NET 为 ...

  9. ORM之Entity Framework(EF)

    ORM之Entity Framework(EF) 一.下载安装: nuget 搜索Entity Framework安装 EntityFramework.Extension是个扩展库根据需要安装 二.使 ...

随机推荐

  1. 华为云(ECS)-linux服务器中-Ubuntu图形界面安装-解决root登录受限-VNCviwer/Teamviwer远程访问教程

    安装ubuntu-desktop .更新软件库 apt-get update .升级软件 apt-get upgrade .安装桌面 apt-get install ubuntu-desktop 解决 ...

  2. 为什么面试你要25K,HR只给你20K?

    周末了,我们来聊个轻松的话题,关于涨薪,哈哈~ 前阵子,栈长给大家分享了<为什么公司宁愿 25K 重新招人,也不给你加到 20K?>,今天我们来聊一个差不多的话题: 为什么面试你要25K, ...

  3. Haskell学习-functor

    原文地址:Haskell学习-functor 什么是Functor functor 就是可以执行map操作的对象,functor就像是附加了语义的表达式,可以用盒子进行比喻.functor 的定义可以 ...

  4. Vue 进阶之路(七)

    之前的文章我们对 vue 的列表输出做了介绍,本章我们来看一下 vue 的组件 component. <!DOCTYPE html> <html lang="en" ...

  5. WebRTC系列(1)-手把手教你实现一个浏览器拍照室Demo

    1.WebRTC开发背景 由于业务需求,需要在项目中实现实时音视频通话功能,之前基于浏览器开发的Web项目要进行音视频通话,需要安装flash插件才能实现或者使用C/S客户端进行通信.随着互联网技术的 ...

  6. Python爬虫入门这一篇就够了

    何谓爬虫 所谓爬虫,就是按照一定的规则,自动的从网络中抓取信息的程序或者脚本.万维网就像一个巨大的蜘蛛网,我们的爬虫就是上面的一个蜘蛛,不断的去抓取我们需要的信息. 爬虫三要素 抓取 分析 存储 基础 ...

  7. SpringBoot当中如何整合mybatis和注入

    [学习笔记] 6.整合mybatis和注入: 马克-to-win@马克java社区: 根据第3部分的helloworld例子,用那个项目做底子.pom.xml只需要加入mybatis和mysql的部分 ...

  8. salesforce初探

      Salesforce的商业模式? 从做CRM SAAS起家,可以理解为在线CRM,不需要硬件和服务器,输入用户名和密码就能登陆使用.2007年推出PaaS平台Force.com,可以说,它依托CR ...

  9. oracle如何查看当前有哪些用户连接到数据库

    可以执行以下语句:select username,serial#, sid from v$session; ---查询用户会话alter system kill session 'serial#, s ...

  10. Tomcat更新方法

    tomcat更新方法最简单的就是上官网下载最新版的压缩包,然后用新版本的 lib 文件替换掉旧版本的 lib 文件 具体方法(偷懒做个搬运工):https://jingyan.baidu.com/ar ...