带着问题去思考!大家好
上篇 概念性讲述CRQS(https://www.cnblogs.com/ccaa/p/12545582.html)
这篇我们主要讲在.NET CORE中的数据访问,数据访问我们常常会想到Entity Frameword Core。这是新面孔,是6.x的基础上专门设计的。
1:将其接来下的数据库访问类放到一个独立的类库中,独立起来。
2:获取连接字符串
public class MyOwnDatabase:DbContext { public MyOwnDatabase(string connStringOrDbName="name=xxx"):base(connStringOrDbName) { } }
DbContext类通过参数接受连接字符串,从web.config文件中获取连接字符串,或者appsettings.json,或者自定义XML。
3:将EF上下文与ASP.NET Core DI集成
理想的作用域是每个请求,这意味着同一个HTTP请求内的所有调用方会共享同一个实例
public void ConfigureServices(IServiceCollection services) { var connString=".."; services.AddScoped(()=>new MyOwnDatabase(connString)); }
直接注入控制器或存储库
public class SomeController:Controller { private readonly MyOwnDatabase _context; public SomeController(MyOwnDatabase context) { _context=context; } }
上面的代码段是将一个DB上下文注入一个控制器来中,不建议这种用法,会使得控制器比较臃肿/
ADO.NET适配器
在ASP.NET Core2.0中。又引用了原来的ADO.NET API的一些组件。有DataTable独享,数据读取器和数据适配器。
1:发出SQL命令
var conn=new SqlConnection(); conn.ConnectionString="..."; var cmd= new SqlCommand("SELECT * FROM customers",conn);
准备过后,通过一个打开的连接发出命令
conn.Open(); var reader=cmd.ExecuteReader(CommandBehavior.CloseConnection); reader.Clone();
由于打开数据读取器的时候会请求关闭连接的行为,因此在关闭读取器时,连接将自动关闭,SqlCommand类的几个方法能够执行命令。
执行方法 | 描述 |
ExecuteNonQuery | 执行命令,但不返回值,适用于非查询语句,UPDATE |
ExecuteReader | 执行命令,返回一个指定输出流的开始位置的游标,适用查询命令 |
ExecuteScalar | 执行命令,并返回单个值,适用于返回一个标量值的查询命令。MAX或COUNT |
Execute.XmlReader | 执行命令,返回一个XML读取器,适用返回XML内容的命令 |
多种选项,可用来获取业务需要的执行SQL语句或存储过程的结果。遍历一个数据读取器的记录
var reader=cmd.ExecuteReader(CommandBehavior.CloseConnection); while(reader.Read()) { var column0=reader[0]; var colum1=reader.GetString(1) } reader.Clone();
2:将数据加载到已断开连接的容器
如果处理一个很长的响应,同时使占用的内存量最少,那么特别适用使用读取器,如果是其他情况,更好的方法是将查询结果加载到一个已断开连接的容器,如DataTable对象,
conn.Open(); var reader=cmd.ExecuteReadr(CommandBehavior.CloseConnection); var table = new DataTable("Customers"); table.Colums.Add("FirstName"); table.Colums.Add("LastName"); table.Colums.Add("CountryCode"); table.Load(reader); reader.Close();
DataTable对象是具有架构,关系和逐渐的数据库表的内存版本。要填充一个DataTable对象,最简单的方法是获取一个数据读取游标,并加载声明的列表中的所有内容。映射是按照列索引进行的。Load方法背后的实际代码非常接近前面看到的循环,一般来说,可以采取的最安全的方法是使用Dispose模式,在C#using语句中创建数据库连接。
3:通过适配器获取数据
var conn=new SqlConnection(); conn.ConnectionString="..."; var cmd=new SqlCommand("SELECT * FROM customers",conn); var table =new DataTable(); var adapter=new SqlDataAdapter(cmd); adapter.Fill(table);
将数据加载到内存容器,最简洁的方式是使用数据适配器,数据适配器是一个汇总了整个查询过程的组件。
完整的O/RM和微型O/RM区别
重生产效率使用EF,存在大量的示例和功能,对命令进行内部优化。
微型O/RM占内存量小。功能少,缺少二级缓存和对关系的内置支持。
二级缓存指框架管理着额外的一层缓存,负责在配置的一定时间内持久化多个连接和事务的结果。EF不支持。EF Core有一个扩展项目。NHibernate支持。
二级缓存并不是区分主要的东西。主要是即对关系的支持
微型O/RM框架Dapper框架,NPoco框架,Insight.Database,PetaPoco
Dapper就性能而言,单个查询。Dapper比EF最多快10倍。