一、 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. MySQL 复制 - 性能与扩展性的基石 4:主备切换

    一旦使用 MySQL 的复制功能,就很大可能会碰到主备切换的情况.也许是为了迭代升级服务器,或者是主库出现问题时,将一台备库转换成主库,或者只是希望重新分配容量.不过出于什么原因,都需要将新主库的信息 ...

  2. ES 15 - Elasticsearch中的数据类型 (text、keyword、date、geo等)

    目录 1 核心数据类型 1.1 字符串类型 - string(不再支持) 1.1.1 文本类型 - text 1.1.2 关键字类型 - keyword 1.2 数字类型 - 8种 1.3 日期类型 ...

  3. 引用provinces.js的三级联动

    第一次写随笔   应该写的不是太好   请多多见谅 我这次是在网上发现了一个三级联动    也是给新人一个福利 这个是你需要新建个 JavaScript 文件  并复制到你新建的文件里面 var pr ...

  4. SmartSql Redis 分布式缓存

    安装 SmartSql.Cache.Redis Install-Package SmartSql.Cache.Redis Cache 配置 <Cache Id="T_Test.Redi ...

  5. 1.JAVA-Hello World

    1.Java开发介绍 J2SE:Java 2 Platform Standard Edition(2005年之后更名为JAVA SE). 包含构成Java语言核心的类.比如:数据库连接.接口定义.数据 ...

  6. Linux遗忘root密码的其中两种解决方法

    由于安全的需要,系统一般只有一个root用户,因此若遗忘root用户的登录密码,因此需要通过其他途径进行修改密码.1.通过单用户模式(1)重启系统,按任意键进入grub菜单.出现grub菜单时,按↑, ...

  7. DataPipeline加入Linux基金会下OpenMessaging社区

    近日,国内领先的“iPaaS+AI”一站式大数据融合服务提供商DataPipeline宣布加入Linux基金会旗下OpenMessaging开源社区,将与OpenMessaging开源社区其他成员阿里 ...

  8. 【原】无脑操作:Gitblit服务器搭建及IDEA整合Git使用

    背景:虽然有GitHub.GitLab这样强大的Git仓库,但是涉及私有Git库要收费,所以自己动手搭建免费的用用 环境:windows 7 旗舰版.JDK 1.8.IDEA 2017 ------- ...

  9. 第七周LINUX学习笔记

    HTTP的基本操作 3月17资源子网和通信子网套接字:两类    socket:IP port             IP:port            Ip.port unix sock:基于文 ...

  10. echarts切换tab时,第一个图表显示,第二个图表不显示的解决办法

    首先这种情况,我在网上看到了好多人问,确实也有正解,但是只是说出了其错误出现的原因,并没有给出解决方法. 我也是深受其害,所以呢,在这里记录一下,分享给还在困扰着的你们,迅速找出解决办法. 首先,我先 ...