博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Entity Framework Core - CURD
阅读量:5248 次
发布时间:2019-06-14

本文共 6505 字,大约阅读时间需要 21 分钟。

【EF框架】DbContext的使用:

DBComtext使用

DbContext类是EntityFramework(简称 EF)中的一个类,可以理解为一个数据库对象的实例。在EF中,无需手动的拼接SQL语句对数据库进行增删改查,而是通过DbContext来进行相应操作。

DbContext类

DbContext是负责与数据交互作为对象的主要类。DbContext负责以下活动:

(1)EntitySet: DbContext包含映射到数据库表的所有实体的实体集(DbSet )。
(2)查询(Querying): DbContext将LINQ-to-Entities查询转换为SQL查询并将其发送到数据库。
(3)更改跟踪(Change Tracking):跟踪实体在从数据库查询后发生的更改。
(4)持久数据(Persisting Data):它还根据实体的状态对数据库执行插入,更新和删除操作。
(5)缓存(Caching): DbContext默认进行一级缓存。它存储在上下文类生命周期中已经被检索的实体。
(6)管理关系(Manage Relationship): DbContext还使用DB-First或Model-First方法使用CSDL,MSL和SSDL或者使用Code-First方法使用流利的API来管理关系。
(7)对象实现(Object Materialization): DbContext将原始表数据转换为实体对象。

EF core跟以前的EF差距非常大,view(视图)无法通过dbfirst生成了,存储过程也一样(虽然我现在开始转codEFirst了)。 然而,如果真的想直接执行sql语句怎么办? 我们发现context下的Database属性跟以前也不一样了,只能做些事务操作,没有执行sql了。可以执行sql的变成了每张具体的表(DbSet)下面的FromSql方法了(需要显式引用Microsoft.EntityFrameworkCore命名空间)。 但是这个方法存在问题,只能返回该表类型的结果,无法返回任意类型。

可以使用linq查询多张表的数据

public List
QueryAUser(){ //定义了上下文实体 excellentmcoinEntities dbcontext = new excellentmcoinEntities(); var allUser = (from u in dbcontext.t_user join g in dbcontext.t_grade on u.gradeID equals g.gradeID orderby u.totalMcoin descending select new userModel() { userID = u.userID, userName = u.userName, userGrade = g.userGrade, totalMcoin = u.totalMcoin, gradeID = g.gradeID, }).ToList(); return allUser;}

EFCore的级联删除(可优化)减少查询

public override async Task
> DeleteAsync(Guid Id){ var data = await DbSet.Include(x => x.UserAuthApplyOfDriver) .Include(x => x.UserAuthApplyOfVehicle) .Include(x => x.UserAuthApplyOfEnterprise) .Include(x => x.UserAuthApplyOfLinePrice) .Include(x => x.User) .FirstOrDEFaultAsync(x => x.Id ==Id); if (data.UserAuthApplyOfVehicle != null) { var vehicles = Context.Set
().Where(x => x.UserAuthApplyId == Id); Context.Set
().RemoveRange(vehicles); } if (data.UserAuthApplyOfDriver != null) { var drivers = Context.Set
().Where(x => x.UserAuthApplyId == Id); Context.Set
().RemoveRange(drivers); } if (data.UserAuthApplyOfEnterprise != null) { var enterprises = Context.Set
().Where(x => x.UserAuthApplyId == Id); Context.Set
().RemoveRange(enterprises); } if (data.UserAuthApplyOfLinePrice != null) { var linePrices = Context.Set
().Where(x => x.UserAuthApplyId == Id); Context.Set
().RemoveRange(linePrices); } return await base.DeleteAsync(Id);}

使用FluentAPI

流畅接口是由Martin Fowler和Eric Evans创造的,流畅API意味着你构建一个API需要遵循以下要点:

1.API用户能够容易理解API
2.API为完成一个任务能够执行一系列动作,比如Java中可以看成是一系列方法调用,方法链。
3.每个方法名称应该是与业务领域相关的专门术语
4.API应该能提示指导API用户下一步用什么,以及某个时刻用户可能采取的操作。
参考:

为了更改约定和映射,可以使用 DbContext 类中的 OnModelCreating 方法。

注意 : 数据库将某个字段从不能为空改为可以非空,需要在数据库中去除约束,还得在OnModelCreating中去除必填代码约束。因为 OnModelCreating 执行的优先级也高

在OnModelCreating方法下使用

public class FluentApiDb:DbContext {     public DbSet
Courses { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity
().Property(o => o.Title).HasMaxLength(20); } }

新增一个类,在OnModelCreating中引用

public class FluentApiDb:DbContext {     public DbSet
Teacher { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new TeacherMap()); modelBuilder.Configurations.Add(new StudentMap()); base.OnModelCreating(modelBuilder); } }

通过反射动态加入。利:自动加入,无需人工反复加;弊:影响性能

public class FluentApiDb:DbContext    {        public DbSet
Teacher { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { var typesToRegister = Assembly.GetExecutingAssembly().GetTypes() .Where(type => !String.IsNullOrEmpty(type.Namespace)) .Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDEFinition() == typeof(EntityTypeConfiguration<>)); foreach (var type in typesToRegister) { dynamic configurationInstance = Activator.CreateInstance(type); modelBuilder.Configurations.Add(configurationInstance); } base.OnModelCreating(modelBuilder); } }

FluentAPI详细用法

  • 设置主键
    cs modelBuilder.Entity<x>().HasKey(t => t.Name);
  • 设置联合主键
    cs modelBuilder.Entity<x>().HasKey(t =>new{t.Name,t.ID} );
  • 取消数据库字段标识(取消自动增长)
    cs modelBuilder.Entity<x>().Property(t=>t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
  • 设置数据库字段标识(自动增长)
    cs modelBuilder.Entity<Teacher>().Property(t =>t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
  • 设置字段最大长度

    modelBuilder.Entity
    ().Property(t => t.Name).HasMaxLength(100);
  • 设置字段为必需
    cs modelBuilder.Entity<ClassA>().Property(t =>t.Id).IsRequired();
  • 属性不映射到数据库

    modelBuilder.Entity
    ().Ignore(t => t.A);
  • 将属性指定数据库列名:
    cs modelBuilder.Entity<ClassA>() .Property(t => t.A) .HasColumnName("A_a");
  • 级联删除(数据库默认是不级联删除的)
    cs modelBuilder.Entity<Course>().HasRequired(t => t.Department).WithMany(t => t.Courses).HasForeignKey(d => d.DepartmentID).WillCascadeOnDelete();
  • 设置为Timestamp
    cs modelBuilder.Entity<OfficeAssignment>() .Property(t => t.Timestamp) .IsRowVersion();
  • 表1对0..1(Instructor实体可以包含零个或一个OfficeAssignment)

    modelBuilder.Entity
    ().HasRequired(t => t.Instructor).WithOptional(t => t.OfficeAssignment);
  • 表1对1
    cs modelBuilder.Entity<Instructor>().HasRequired(t => t.OfficeAssignment).WithRequiredPrincipal(t => t.Instructor);
  • 表1对n(Department为主表)
    cs modelBuilder.Entity<Staff>() .HasRequired(c => c.Department) .WithMany(t => t.Staffs)
  • 指定外键名(指定表Staff中的字段DepartmentID为外键)
    cs modelBuilder.Entity<Staff>() .HasRequired(c => c.Department) .WithMany(t => t.Staffs) .Map(m => m.MapKey("DepartmentID"));
  • 表n对n
    cs modelBuilder.Entity<Course>() .HasMany(t => t.Instructors) .WithMany(t => t.Courses)
  • 表n对n指定连接表名及列名

    cs modelBuilder.Entity<Course>() .HasMany(t => t.Instructors) .WithMany(t => t.Courses) .Map(m => { m.ToTable("CourseInstructor"); m.MapLEFtKey("CourseID"); m.MapRightKey("InstructorID"); });

参考:

EF Core中如何正确地设置两张表之间的关联关系:
官方文档:
翻译官方文档:

转载于:https://www.cnblogs.com/zhangqgd/p/11179794.html

你可能感兴趣的文章
RabbitMQ、Redis、Memcache、SQLAlchemy
查看>>
03 线程池
查看>>
手机验证码执行流程
查看>>
设计模式课程 设计模式精讲 2-2 UML类图讲解
查看>>
Silverlight 的菜单控件。(不是 Toolkit的)
查看>>
jquery的contains方法
查看>>
linux后台运行和关闭SSH运行,查看后台任务
查看>>
桥接模式-Bridge(Java实现)
查看>>
303. Range Sum Query - Immutable
查看>>
【★】浅谈计算机与随机数
查看>>
C# Dynamic通用反序列化Json类型并遍历属性比较
查看>>
前台freemark获取后台的值
查看>>
Leetcode: Unique Binary Search Trees II
查看>>
C++ FFLIB 之FFDB: 使用 Mysql&Sqlite 实现CRUD
查看>>
Spring-hibernate整合
查看>>
c++ map
查看>>
exit和return的区别
查看>>
Django 相关
查看>>
比较安全的获取站点更目录
查看>>
UVA11374 Airport Express
查看>>