要专业系统地学习EF前往《你必须掌握的6.x与Core 2.0》这本书的作者(汪鹏,)的博客:
实体状态
通过EF上下文与数据库交互的实体,都会被EF跟踪,并且实体会被分配状态 。
我们在添加修改删除数据的时候没有注意到这个实体状态,是因为在我们调用Add()、()这些方法时,其实就是对实体的状态进行改变
实体状态都有五种,在.Data.命名空间下的类里面
public enum EntityState{Detached = 1,Unchanged = 2,Added = 4,Deleted = 8,Modified = 16}
View Code
1.Added状态针对添加操作,当标记为此状态时 , 表明实体被上下文所追踪但是不存在与数据库中
什么意思?就是在调用时,如果发现有实体是这个状态,就会将该实体添加到数据库中
2. 实体被上下文追踪,但是存在于数据库中的值未发生改变
这说的是,你从数据库中查出的数据就是状态,可不是值没有改变嘛?可不就是被跟踪了吗?
3. 实体被上下文跟踪并存在于数据库中,同时部分或者所有属性值已经被更改
这个还是好理解的,不过要注意,这些状态都说了,要被上下文追踪 。
4. 实体被上下文跟踪并存在于数据库中 , 当标记为状态时,时数据将在数据库中被删除
5. 这个就是表示没有被上下文追踪,只有通过上下文得到的实体对象才会有被跟踪,才会有其他状态 , 否则就是
我们来把各种被操作的实体的状态打印出来看看,查看实体状态,用Entry()方法
我们现在凭空new 一个对象
using (EFDbContext db = new EFDbContext()){Book book1 = new Book { Name = "演员自我修养", Number = "NO8973424", Price = 21.5m };var state = db.Entry(book1).State;Console.WriteLine(state);//Detached}
View Code
当我们调用Add方法,实体状态变为Added
Book book1 = new Book { Name = "演员自我修养", Number = "NO8973424", Price = 21.5m };db.Books.Add(book1);var state = db.Entry(book1).State;Console.WriteLine(state);//Added
View Code
然后将这个实体添加到数据库,然后查询出来 , 这个查询出来的实体状态为
Book book1 = new Book { Name = "演员自我修养", Number = "NO8973424", Price = 21.5m };db.Books.Add(book1);db.SaveChanges();var state = db.Entry(book1).State;Console.WriteLine(state);//Unchanged
View Code
让我想不到的是,我不用查询,直接查看他的状态就是,有点神奇
我们查询出一个实体 , 然后修改某个属性值,状态变为
var res = db.Books.ToList().FirstOrDefault();res.Name = "新华字典";var state = db.Entry(res).State;Console.WriteLine(state);//Modified
View Code
我们调用方法,实体状态变为 。我刚刚还为状态感到神奇呢 , 现在看来我居然只有通过这种方式来获得状态
var res = db.Books.ToList().FirstOrDefault();db.Books.Remove(res);var state = db.Entry(res).State;Console.WriteLine(state);//Deleted
View Code
上下文没有提供方法,所以我们要通过更改实体状态的方式来更新数据
var res = db.Books.ToList().FirstOrDefault();res.Name = "新华字典";db.Entry(res).State = System.Data.Entity.EntityState.Modified;db.SaveChanges();
View Code
关于实体状态就先浅尝辄止了
文章插图
实现接口和接口数据集支持查询方法的差异
我在学LINQ(语言集成查询)时对这两个接口稍微有点了解,之后看别人的博客,详解接口,我看不太明白,很气馁
LINQ是什么,他是想对查询语法做一个统一 , 我们在数据库中查询数据要写SQL语句,查询XML用DOM操作,那能不能来个统一的方式,不要让我去学习那么多的查询语句了,那么LINQ就来了
写LINQ有两种方法,一个是写查询语句,像什么from a in lista;这样的,还一个就是调用方法,像Where()、()……
这两种方式没什么区别,只不过一些聚合查询必须得调用方法才行,大部分的查询语句和方法都能来
还有一点,LINQ里面有延迟加载 , 聚合查询会立即执行,官网上面写了有,什么方法会立即执行查询
LINQ的那些查询方法都是扩展在类上的,所以我们也可以通过扩展这个类来扩展LINQ
我来说一下和这两个接口,查询内存中的数据都是实现的接口,查询远程数据是实现的接口
List list = new List { 12, 32, 34, 55, 66 };list.Where();var res = db.Books.Where();
View Code
他们之间很多方法都匹配,但是有一些方法不行,上面的两个Where方法不是一样的,一个返回的是,一个返回的
Last 和
这两个方法在中不支持,我也就搞不明白了 , 算了,反正这两方法我真是一次都没用过
当我对上下文的数据集调用方法时,报错,n 不支持异常
.n: LINQ todoes notthe'..Book [Book](.Linq.`1[..Book])' , and thisbeinto a store .
方法
Book book1 = new Book { Id = Guid.NewGuid().ToString(), Name = "自我修养", Price = 30m };Book book2 = new Book { Id = Guid.NewGuid().ToString(), Name = "新华字典", Price = 30m };Book book3 = new Book { Id = Guid.NewGuid().ToString(), Name = "天国之秋", Price = 30m };List bookList = new List();bookList.Add(book1);bookList.Add(book2);bookList.Add(book3);bool boo = bookList.Contains(book1);Console.WriteLine(boo);//Truevar frist = db.Books.FirstOrDefault();db.Books.Contains(frist);//报错 NotSupportedException
View Code
我对内存中的数据进行查询,和远程查询数据库中的数据,得到上面的结果 。EF不支持方法,虽然这个方法我几乎不使用,感觉甚至都不想去了解这些差异的东西了 。但是刚刚想到,万一我使用到了呢?然后我发现在中是可以的,但是查询EF上下文的数据集为什么又不行呢?
然后我就只会怀疑是不是自己写错了,然后我能想到我怎么想都不知道错在哪里,然后独自抓耳挠腮 , 其实现在知道是系统的问题,那么就不会动不动就怀疑人生了 。
但是如果你对上下文中的数据集进行(x=>x.Name)查询之后,得出的List集合再调用方法又是可以的 , 所以对于简答类型的集合可以,复杂类型的不行
var res = db.Books.Select(x => x.Name);var res2 = res.Contains("新华字典");//TrueConsole.WriteLine(res2);
View Code
Case和
这两方法主要查询集合里面指定类型的数据
case方法主要针对基元类型进行查询(int、……),总之相当不好用 , 它是全盘转换,类型不匹配,就抛出异常,这有什么用?可以判断一个集合中的数据是不是都是同一类型,但是现在都使用泛型集合List,哪还使用List
List