1、实体状态

我们通过EF来对数据库进行操作并持久化到数据库,那么EF必然通过EF上下文来维护实体的状态,明确知道每一个状态所对应的操作。也就是说EF通过上下文负责跟踪实体的状态。EF实体状态存在命名空间System.Data.Entity下的EntityState枚举中

1.1、Added

Added状态针对添加操作,当标记为此状态时,表名实体被上下文追踪但是不存在数据库中,当调用SaveChange()的时候会插入到数据库中。标记Added状态有两种:一种是间接标记,通过Add方法调用;另一种显示标记通过Entry方法调用代码如下

 var cus = new Customer() {
Name="魏杨杨",
Age=,
Email="30119459@qq.com",
AddTime=DateTime.Now
};
db.Customer.Add(cus);
db.SaveChanges();
//或者是
var cus = new Customer() {
Name="魏杨杨",
Age=,
Email="30119459@qq.com",
AddTime=DateTime.Now
};
db.Entry(cus).State = System.Data.Entity.EntityState.Added;
db.SaveChanges();

1.2、UnChangeed

实体类被EF上下文所追踪,但是存在数据库中的值未发生改变。若一个实体类不存在与数据库,但是该实体要被上下文所追踪,同时该实体值未发生改变就可以通过Attach进行附加追踪,然后标记为UnChanged状态

using (var db =new  WYDBContext())
{
var cus = new Customer() {
Name="魏杨杨",
Age=,
Email="30119459@qq.com",
AddTime=DateTime.Now
};
          db.Customer.Attach(cus);
db.Entry(cus).State = System.Data.Entity.EntityState.Unchanged;
db.SaveChanges();
}

1.3、Modified

实体被EF上下文所追踪并存在于数据库中,同时部分或者所有属性值已经被更改,当调用SaveChange()时则更新到数据库中。注意:在EF6.0以上的版本中不存在Update方法。看数据库里面的值

using (var db =new  WYDBContext())
{
var cus = new Customer() {
Zj=,
Name="魏杨杨22",
Age=,
Email="30119459@qq.com",
AddTime=DateTime.Now
}; db.Entry(cus).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
}

一般我做更改的时候都不会这么麻烦,当修改的时候只要传来这一列的参数ID 查找出当前列就直接修改了,我这种方法用的多一点:比如

public ActionResult Edit(int id)
{
using (var db = new WYDBContext())
{
var model = db.Customer.Find(id);
model.Name = "Wyy333";
model.Age = ;
db.SaveChanges();
return View(model);
} }

1.4、Deleted

实体类被EF上下文所追踪并存在于数据库中,当标记为Deleted状态时,调用SaveChange()方法时数据将在数据库中删除,和Added状态一样可以调用Remove或者RemoveChange方法标记实体为Deleted状态,或者通过Entry方法标记

using (var db =new  WYDBContext())
{
var cus = new Customer() {
Zj=,
Name="魏杨杨22",
Age=,
Email="30119459@qq.com",
AddTime=DateTime.Now
}; db.Entry(cus).State = System.Data.Entity.EntityState.Deleted;
db.SaveChanges();
} //或者
using (var db =new WYDBContext())
{
var cus = new Customer() {
Zj=,
Name="魏杨杨22",
Age=,
Email="30119459@qq.com",
AddTime=DateTime.Now
}; db.Customer.Remove(cus);
db.SaveChanges();
} //或者这种删除是最常见了的吧我见过的都是这样的
using (var db = new WYDBContext())
{
var model = db.Customer.Find(id);
db.Customer.Remove(model);
db.SaveChanges();
return View(model);
}

2、加载关联数据

在EF6.0 以上的版本中,数据加载方式有3种:延迟加载,饥渴加载、显示加载。三种加载方式都有其场景,利用不同将导致性能问题。

2.1、Lazy Loading(延迟加载)

顾名思义就是当我门需要的时候才加载也就是说的按需加载。当第一次访问指向实体或者实体的属性时,实体或者实体的集合将从数据库加载,访问导航属性是相关的对象或者子对象不会自动加载。virtual 的导航属性就是延迟加载。摸人家情况下EF启动延时加载。我们也可以在EF上下文派生类中手动关闭延迟加载

在订单里面加点数据

当查询Customer的时候看到Order还没有计算,

下面来获取Order数据

现在我们关闭延时加载效果 再看看

public WYDBContext():base("SqlConn")
{
Configuration.LazyLoadingEnabled = false;
}

这不就报错了吗。现在我们就看到延迟加载的本质:只有当调用者使用的时候才会计算结果。

2.2、Eager Loading(饥饿加载)

查询实体的时候可以加载相关实体或者子实体作为查询的一部分,加载父对象同时加载子对象,在EF中可以使用DbSet<T>.Include()方法来实现饥渴加载。和延迟加载不同的是我们用与不用子对象都会被加载进来。

using (var db =new  WYDBContext())
{
var cs = db.Customer.Include("Order").ToList();
var cs2 = db.Customer.Include(p=>p.Order).ToList();//using System.Data.Entity; }

现在可以看出饥饿加载的本质:提前加载所有数据

2.3 Explicitly Loading(显示加载)

延迟执行有延迟加载个显示加载两种方式,即使我们禁用了延迟加载,然然可以通过显示加载来延迟加载相关实体,通过DbEntityEntry<T>.Reference("").Load()加载实体。通过DbEntityEntry<T>.Collection("").Load()加载集合

 using (var db =new  WYDBContext())
{
var cs = db.Customer.ToList().FirstOrDefault();
var order = db.Entry(cs).Collection(x => x.Order).Query().ToList(); var or = db.Order.ToList().FirstOrDefault();
db.Entry(or).Reference(x => x.Customer).Load() ; }

效果如期而至就不贴了。可以总结出显示加载的本质:即使禁用延迟加载任然可以延迟执行

3、在Ef中执行Sql

3.1、在实体上执行原始查询

在EF中可以通过SqlQuery来查询数据 有如下两种方法

efDbContext.Database.SqlQuery<实体类名>(string sql , params object[] parameters)

efDbContext.实体类.SqlQuery(string sql , params object[] parameters)

Tolist()后将所有数据加载到内存中;

using (var db =new  WYDBContext())
{
//结果会保存到数据库中
var c2 = db.Customer.SqlQuery("Select * from Customer").ToList();
c2.Last().Email = "wyy22@qq.com";
db.SaveChanges(); //结果不会保存到数据库中
var c1= db.Database.SqlQuery<Customer>("Select * from Customer").ToList();
c1.Last().Email = "wyy@qq.com";
db.SaveChanges();
}

这里要把列名弄了跟数据库里面的对应就是不要去别名了 我出错是因为这里一个是Name一个是NameWyy哈哈 挖坑给自己跳

 [Column("NameWYY", TypeName = "nvarchar")]//我加了WYY看效果
[StringLength(, ErrorMessage = "{0}长度不能超过50个字符")]
[Display(Name = "姓名")]
public string Name { get; set; }

注意:

efDbContext.Database.SqlQuery<实体类名>(string sql , params object[] parameters) 此方法查询在数据库database上,实体不会被上下文跟踪

efDbContext.实体类.SqlQuery(string sql , params object[] parameters)查询在上下文的实体集合DbSet上,实体会被上下文跟踪

3.2、在EF中执行Sql:删除,修改

using (var db =new  WYDBContext())
{
//第一种
string ema = "wwww@qq.com";
string sql = $"Update Customer set email='{ema}' where Zj=1;";
db.Database.ExecuteSqlCommand(sql);
//第二种 可以防止Sql注入
SqlParameter[] para = { new SqlParameter("@Emale", "wwww@qq222.com"),new SqlParameter("@Zj",) };
var sql1 = "Update Customer set email=@Emale where Zj=@Zj;";
db.Database.ExecuteSqlCommand(sql1,para);
}

删除也是一样的

EF 学习系列三 数据操作数据加载及EF中执行Sql的更多相关文章

  1. Android学习笔记_36_ListView数据异步加载与AsyncTask

    一.界面布局文件: 1.加入sdcard写入和网络权限: <!-- 访问internet权限 --> <uses-permission android:name="andr ...

  2. 深入浅出JVM(一):你写得.java文件是如何被加载到内存中执行的

    众所周知,.java文件需要经过编译生成.class文件才能被JVM执行. 其中,JVM是如何加载.class文件,又做了些什么呢? .class文件通过 加载->验证->准备->解 ...

  3. MVC学习系列6--使用Ajax加载分部视图和Json格式的数据

    Ajax的应用在平时的工作中,很是常见,这篇文章,完全是为了,巩固复习. 我们先看看不使用json格式返回分部视图: 先说需求吧: 我有两个实体,一个是出版商[Publisher],一个是书[Book ...

  4. 【Spring源码深度解析学习系列】Bean的加载(六)

    Bean的加载所涉及到的大致步骤: 1)转换对应beanName 为什么需要转换beanName呢?因为传入的参数可能是别名,也可能是FactoryBean,所以需要一系列的解析,这些解析内容包括如下 ...

  5. 使用异步任务加载网络上json数据并加载到ListView中

    Android中使用网络访问来加载网上的内容,并将其解析出来加载到控件中,是一种很常见的操作.但是Android的UI线程(也就是主线程)中是不允许进行耗时操作的,因为耗时操作会阻塞主线程,影响用户体 ...

  6. EF如何操作内存中的数据以及加载相关联表的数据:延迟加载、贪婪加载、显示加载

    之前的EF Code First系列讲了那么多如何配置实体和数据库表的关系,显然配置只是辅助,使用EF操作数据库才是每天开发中都需要用的,这个系列讲讲如何使用EF操作数据库.老版本的EF主要是通过Ob ...

  7. Echarts使用及动态加载图表数据 折线图X轴数据动态加载

    Echarts简介 echarts,缩写来自Enterprise Charts,商业级数据图表,一个纯JavaScript的图表库,来自百度...我想应该够简洁了 使用Echarts 目前,就官网的文 ...

  8. [翻译 EF Core in Action 2.4] 加载相关数据

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

  9. JPA数据懒加载LAZY配合事务@Transactional使用(三)

    上篇博文<JPA数据懒加载LAZY和实时加载EAGER(二)>讲到,如果使用懒加载来调用关联数据,必须要保证主查询session(数据库连接会话)的生命周期没有结束,否则,你是无法抽取到数 ...

随机推荐

  1. input标签前台实现文件上传

    值得注意的是:当一个表单里面包含这个上传元素的时候,表单的enctype必须指定为multipart/form-data,method必须指定为post,浏览器才会认识并正确执行.但是还有一点,浏览器 ...

  2. python-字符编码数据类型转换

    1 - 编码格式转换 1.1 编码格式介绍 字符集 介绍 ASCII ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符 ANSI ANSI是一种字符代码,为使计算 ...

  3. Native memory allocation (mmap) failed to map xxx bytes for committing reserved memory

    遇到问题 在服务器上运行 nexus 出现Native memory allocation (mmap) failed to map 838860800 bytes for committing re ...

  4. H3C HDLC概述

  5. 【t018】派对

    Time Limit: 1 second Memory Limit: 256 MB [问题描述] N头牛要去参加一场在编号为X(1≤X≤n)的牛的农场举行的派对(1≤N≤1000),有M(1≤M≤10 ...

  6. Python--day37--进程锁

    进程锁的示意图: 锁.py: #锁 #火车票 import json import time from multiprocessing import Process from multiprocess ...

  7. java 递归(Recursion)

    现在要求输出一个给定目录中的全部文件的路径. 本程序肯定只能依靠递归的操作完成,因为在一个给定的路径下有可能还是文件夹,那么如果是文件夹的话则肯定要继续列出,重复判断. 递归:程序调用自身的编程技巧 ...

  8. 【u212】&&【t036】最大和

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] N个数围成一圈,要求从中选择若干个连续的数(注意每个数最多只能选一次)加起来,问能形成的最大的和. [ ...

  9. CF241B Friends

    CF241B Friends 和Tree and Xor思路一样CF1055F Tree and XOR 直接找到第k大val,可以直接建出trie,然后按位贪心 考虑比val大的数的和 还是用b[i ...

  10. vue-learning:34 - component - 内置组件 - 动态组件component 和 is属性

    component动态组件 / is属性 让多个组件使用同一个挂载点,并动态切换,这就是动态组件. 必要条件: 组件标签使用<component></component> 动态 ...