一、 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. Actor模型-Akka

    英文原文链接,译文链接,原文作者:Arun Manivannan ,译者:有孚 写过多线程的人都不会否认,多线程应用的维护是件多么困难和痛苦的事.我说的是维护,这是因为开始的时候还很简单,一旦你看到性 ...

  2. Logistic回归(逻辑回归)和softmax回归

    一.Logistic回归 Logistic回归(Logistic Regression,简称LR)是一种常用的处理二类分类问题的模型. 在二类分类问题中,把因变量y可能属于的两个类分别称为负类和正类, ...

  3. 『性能』测试一下 MSSqlHelper 的性能

    本文没啥技术含量,就是测试一下 MSSqlHelper 在 使用反射.不使用反射 的性能对比. 之后,不要问为什么不用 ORM 这类的东西 —— 会有另外的文章 介绍 自己这些年 自己的ORM 升级历 ...

  4. Python中的那些“坑”

    1.哪个是True,哪个是False? 这里要看三组代码: # 第一组: >>>a=256 >>>b = 256 >>>a is b # 第二组: ...

  5. [翻译 EF Core in Action 2.1] 设置一个图书销售网站的场景

    Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...

  6. SSM+Maven+MySQL实现简易的挂机修仙页游

    一段时间没有写过SSM的项目了,最近重新整合框架做了一个小Demo 学Java的萌新可以看一看:大佬呢,欢迎指出不足! 我一直钟爱挂机类游戏,同时也喜欢修仙和武侠小说,于是突发奇想,自己搞一个小游戏? ...

  7. 零基础学Python--------第3章 流程控制语句

    第3章 流程控制语句 3.1程序的结构 计算机在解决某个具体问题时,主要有3种情况,分别是顺序执行所有的语句.选择执行部分语句和循环执行部分语句.程序设计中的3种基本结构为顺序结构.选择结构和循环结构 ...

  8. SQL SERVER 查看所有存储过程或视图里 包含某个关键字的查询语句

    SELECT name, type_desc FROM sys.all_sql_modules s INNER JOIN sys.all_objects o ON s.object_id = o.ob ...

  9. SpringBoot2.0之六 多环境配置

    开发过程中面对不同的环境,例如数据库.redis服务器等的不同,可能会面临一直需要修改配置的麻烦中,在以前的项目中,曾通过Tomcat的配置来实现,有的项目甚至需要手动修改相关配置,这种方式费时费力, ...

  10. docker 发布到私有docker registry

    1.使用vs发布项目到文件夹: 2.在文件夹中新建dockerfile文件, 内容: FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-sli ...