上几个章节都是介绍EF6中Modeling内容,包括注解和Fluent,下面介绍EF6中的常用操作
Operation
EF通过ObjectContext类定义从实体对象到数据库的映射,与ADO.NET中的填充DataSet数据适配器相似,默认的构造函数中从配置文件中读取连接字符串,也可打开链接以EntityConnection实例的形式传递给构造函数
1.它提供以下服务给调用者:
1).跟踪已经检索到的实体对象,若再次查询该对象就从对象上下文中提取它。
2).保存实体的状态信息。可获得已添加、修改和删除对象的信息。
3).更新对象上下文中的实体,把改变的内容写入底层存储器中
2.方法和属性
方法或属性 |
说明 |
Connection |
返回一个与对象上下文关联的DbConnection对象 |
MetadataWorkspace |
返回一个MetadataWorkspace对象,该对象可用于读取元数据和映射信息 |
QueryTimeOut |
使用这个属性可获取和设置对象上下文查询的超时值 |
ObjectStateManager |
属性返回一个ObjectStateManager,会跟踪检索到实体对象和该对象在对象上下文中的变化 |
CreateQuery() |
返回一个ObjectQuery,从存储器中获取数据 |
GetObjectByKey() TryGetObjectByKey() |
依据键值对象状态管理器或底层存储器中返回对象。若键不存在,就抛出一个ObjectNotFoundException类型的异常,而Try方法返回False |
AddObject() |
在对象上下文中添加一个新的实体对象 |
DeleteObject() |
从对象上下文中删除一个对象 |
Attach() AttachTo() |
把分离出的对象附加到存储中,把对象附加回对象上下文中,需要实体对象实现IEntityWithKey接口,AttachTo()方法不需要对象带有键,但它需要一个实体集名称,需要附加实体对象就放在这实体集中 |
ApplyPropertyChanges() |
若对象从对象上下文中分离出来,就修改解除分离出来的对象,在把进行的修改应用与对象上下文中的对象之前,可调用该方法应用这些修改。当分离出来的对象从Web服务中返回,从客户端上修改它,再把它传递给Web服务时,这个方法很有用 |
Refresh() |
实体对象存储在对象上下文中时,存储器中的数据可以修改。为了用存储器中的变化进行刷新,可以使用该方法且可传递一个RefreshMode枚举值。若用于对象的值在存储器和对象上下文中不同,就传递ClientWins值修改存储器中的数据,若传递StoreWins值就修改对象上下文中的数据 |
SaveChanges() |
从对象上下文中添加、修改和删除对象,不会改变底层存储器中的对象,使用该方法可以把这些修改持久化到存储器中 |
AcceptAllChanges() |
把对象上下文中对象的状态改为未修改,Savechanges()隐式调用 |
- IDbSet<TEntity>类
表示上下文中给定类型的所有实体的集合或可从数据库中查询的给定类型的所有实体的集合,有时也会用实现类DbSet<TEntity>,可只创建getter或setter的属性器
CRUD/Querying/Saving Data
1) Create
不仅仅可以通过使用dbset<TEntity>().add方法进行添加也可通过Entry方法的状态修改进行添加
2) Update
先查询需要更新的实体类,然后在断开数据库连接的情况下进行修改实体类信息,再通过Entry修改状态为Modified状态,最后通过保存来连接数据库更新
1) Delete
同样的可以通过直接调用Dbset方法的remove方法移除,也可以通过修改状态方式
3) Delete
同样的可以通过直接调用Dbset方法的remove方法移除,也可以通过修改状态方式
4) Querying
可以创建异步方法,然后通过在方法中使用异步查询函数返回
同样也可以通过异步保存结果
SQL query
同样可以采用原始的sql语句查询,但是只能返回指定的类型查询
若是不是查询*,而是指定对应的列则必须匹配到领域类的名字,否则会异常,如下是可以
而这种情况是会抛出异常
若是要返回一个指定的基本类型则必须使用泛型如下
同样的也可以直接使用数据库命令执行原始SQL命令
DbConfiguration
默认情况下EF6.X读取配置文件的数据库信息,但是也可以根据自定义配置文件来实现个性化的定义,使得定义的类继承DbConfiguration类
然后在配置文件中修改entityFramework节点或者通过构造方法重写,EF不支持在同一个应用域中有多个配置类存在,若是采用特性给不同的配置类将会出现异常。
若是要设置不同的配置在一个配置文件中可以采用如下方式:
首先设置默认连接工厂
然后设置数据库提供者
最后初始化数据库
Interception
DbCommandInterceptor继承该类可以创建数据库执行拦截器,可在执行数据库命令(查询、添加、更新等)拦截响应的日志信息,如ExecuteNonQuery, ExecuteScalar, ExecuteReader 操作的异常信息
然后在配置文件或者代码中进行配置
Transaction
默认情况下在Insert、Update和Delete操作中都使用了事务模型,当调用SaveChanges()时就会触发事务操作。使用事务会用到database.BeginTransaction和Database.UseTransaction
Concurrency Patterns
在EF6.x中为了追踪保存值,设定了多个值来保存,其中包括当前值(即实体属性目前值)和原始值(从数据库或实体查询时,依附在dbContext中值),设置当前值和原始值
1) Getting and setting the current or original value of an individual property
2) Getting and setting the current or original value of an unmapped property
若当前值未映射数据库中,他是可以被读取的
3) Checking whether a property is marked as modified
4) Marking a property as modified
5) Reading current,original,and database values for all properties of an entity
6) Setting current or original values from another object
7) Using DbPropertyValues to access complex properties
乐观并发解决即乐观的尝试将实体保存到数据库,数据自实体加载后未曾更改,但若数据确实发生更改,则将引发异常必须先解决异常才能尝试重新保存
数据库优先模式(Reload)
l 客户端优先模式 (OriginalValues.SetValues)
通常最完美的解决方式是通过用户选择修改原始值和当前值来保存适当值
Store Procedure
EF中也可以通过配置约定运行存储过程,也可以配置多个存储过程带参数
若是所有实体类都需要使用存储过程,则可以统一配置