
西伯利亚属鼠 C#:实体框架EF(entity framework)
发布日期:2024-12-06 11:56 点击次数:171
一、什么是Entity Framework 西伯利亚属鼠
微软官方提供的ORM用具,ORM让建造东谈主员从简数据库观察的代码时候,将更多的时候放到业务逻辑层代码上。EF提供变更追踪、惟一性络续、惰性加载、查询事物等。建造东谈主员使用Linq言语,对数据库操作如同操作Object对象雷同省事。 EF有三种使用场景,1. 从数据库生成Class,2.由实体类生成数据库表结构,3. 通过数据库可视化想象器想象数据库,同期生成实体类。
伦理片段频在线观看百度图片
西伯利亚属鼠
O/RM是什么?
ORM 是将数据存储从域对象自动映射到关系型数据库的用具。ORM主要包括3个部分:域对象、关统共据库对象、映射关系。ORM使类提供自动化CRUD,使建造东谈主员从数据库API和SQL中自若出来。
二、Entity Framework 架构
图片
EDM (实体数据模子):EDM包括三个模子,倡导模子、 映射和存储模子。
倡导模子 ︰ 倡导模子包含模子类和它们之间的关系。孤独于数据库表的想象。
存储模子 ︰ 存储模子是数据库想象模子,包括表、 视图、 存储的经由和他们的关系和键。
映射 ︰ 映射包含相关怎样将倡导模子映射到存储模子的信息。
LINQ to Entities ︰ LINQ to Entities 是一种用于编写针对对象模子的查询的查询言语。它复返在倡导模子中界说的实体。
Entity SQL: Entity SQL 是另一种炉近似于L2E的言语,但相给L2E要复杂的多,是以建造东谈主员不得不只独学习它。
Object Services(对象事业):是数据库的观察进口,阐扬数据具体化,从客户端实体数据到数据库记载以及从数据库记载和实体数据的调度。
Entity Client Data Provider:主要使命是将L2E或Entity Sql调度成数据库不错识别的Sql查询语句,它使用Ado.NET通讯向数据库发送数据可取得数据。
ADO.Net Data Provider:使用法式的Ado.net与数据库通讯
三、Entity Framework开动环境
EF5由两部分构成,EF api和.net framework 4.0/4.5,而EF6是孤独的EntityFramework.dll,不依赖.net Framework。使用NuGet即可安设EF。
图片
四、创建实体数据模子
使用向导创建实体类,或键添加,傻瓜式的~
图片
添加完成之后,.config文献中会添加以下确立
<?xmlversion="1.0"?><configuration><configSections><!-- For more information on Entity Framework configuration, visit http://Go.microsoft.com/fwlink/?LinkID=237468 --><sectionname="entityFramework"type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"requirePermission="false"/></configSections><startup><supportedRuntimeversion="v4.0"sku=".NETFramework,Version=v4.5"/></startup><entityFramework><defaultConnectionFactorytype="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework"/><providers><providerinvariantName="System.Data.SqlClient"type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/></providers></entityFramework><connectionStrings><addname="SchoolDBEntities"connectionString="metadata=res://*/SchoolDB.csdl|res://*/SchoolDB.ssdl|res://*/SchoolDB.msl;provider=System.Data.SqlClient;provider connection string="data source=.\sqlexpress;initial catalog=SchoolDB;integrated security=True;multipleactiveresultsets=True;application name=EntityFramework""providerName="System.Data.EntityClient"/></connectionStrings></configuration>
Context & Entity 类:
每个Entity Data Model 生成一个context类,类数据库每个表生成一个entity类。如在School.edmx中包含的两个热切的文献{EDM Name}.context.tt和{EDM Name}.tt:
图片
School.Context.tt:T4模板用于生成的context类,不错从目次结构中看到School.Context.tt下包含一个School.Context.cs文献。
School.tt:用于生成表映射的实体类。Entity类是POCO类。如Student生成
图片
publicpartialclassStudent { public Student() { this.Courses = new HashSet<Course>(); } publicint StudentID { get; set; } publicstring StudentName { get; set; } publicNullable<int> StandardId { get; set; } publicbyte[] RowVersion { get; set; } publicvirtualStandard Standard { get; set; } publicvirtualStudentAddress StudentAddress { get; set; } publicvirtualICollection<Course> Courses { get; set; } }
图片
五、模板浏览器
以SchoolDB为例,切换到Model View视图下,看到类图结构:
图片
六、DBContext
第四节中提到EDM生成SchoolDBEntities类,该类从System.Data.Entity.DbContext类经受。EntityFramework4.1中Context类从ObjectContext类经受。DbContext类与ObjectContext近似,它对ObjcetContext类进行包装更利于建造的三种花式:CodeFirst、Model First、Database First.
DbContext是EntityFramework很热切的部分,联络域模子与数据库的桥梁,是与数据库通讯的主要类。
图片
DbContext主要阐扬以下活动:
EntitySet::DbContext包含了统共映射到表的entities
Querying:将Linq-To-Entities转译为Sql并发送到数据库
Change Tracking:从数据库取得entities后保留并追踪实体数据变化
Persisting Data:证实entity景色推论Insert、update、delete高唱
Caching:DbContext的默许第一级缓存,在高下文中的生命周期中存储entity
Manage Relationship:DbContext在DbFirst花式中使用CSDL、MSL、SSDL搞定对象关系,Code first中使用fluent api 搞定关系
Object Materialization:DbContext将物理表转成entity实例对象
DEMO
DbContext实例化:
图片
using (var ctx = newSchoolDBEntities()) { //Can perform CRUD operation using ctx here.. } 将DbContext转为ObjectContext using (var ctx = newSchoolDBEntities()) { var objectContext = (ctx as System.Data.Entity.Infrastructure.IObjectContextAdapter).ObjectContext; //use objectContext here.. }
图片
七、Entity Framework中的Entity类型
POCO Entity (Plain Old CLR Object):
不依赖于任何Framework的类的类(also known as persistence-ignorant objects),为Entity Data Model生成CRUD高唱事业。
图片
public class Student { public Student() { this.Courses = new List<Course>(); } public int StudentID { get; set; } public string StudentName { get; set; } public Nullable<int> StandardId { get; set; } public Standard Standard { get; set; } public StudentAddress StudentAddress { get; set; } public IList<Course> Courses { get; set; } }
图片
Dynamic Proxy (POCO Proxy):
Dynamic Proxy是开动时POCO类的代理类,近似POCO类的包装。Dynamic Proxy允许延伸加载(Lazy loading),自动追踪改换。POCO Entity必需自负以下几点才调转为POCO Proxy:
1. 必需声明为public 类
2. 弗成以是sealed类
3. 弗成以是概括类
4. 导航属性必需是public,vitual(Entity包含两种属性,标量属性Scalar properties:Entity自己的字段值,Navigation properties:其它entity的援用如班级-学生)
5. 聚拢属性必需是 ICollection<T>
6. ProxyCreationEnabled 选项必需是true
图片
public class Student { public Student() { this.Courses = new HashSet<Course>(); } public int StudentID { get; set; } public string StudentName { get; set; } public Nullable<int> StandardId { get; set; } public virtual Standard Standard { get; set; } public virtual StudentAddress StudentAddress { get; set; } public virtual ICollection<Course> Courses { get; set; } }
图片
八、Entity Relationships:
图片
九、 Entity Lifecycle
在咱们作念CRUD操作时,要先了解EntityFramework怎样搞定实体景色。每个实体的生命周期内王人会在DbContext高下文中保存一个景色,辩别是
Added Deleted Modified Unchanged Detached
图片
十、Code First、DBFirst、Model First
CodeFirst 限度想象时先界说实体类,用实体类生成数据库
DbFirst 从数据库生成实体类
Model First 使用Visual Studio实体想象器,想象ER,同期生成Entity类和DB
图片
十一、使用查询
三种查询神色1) LINQ to Entities, 2) Entity SQL, and 3) Native SQL
LINQ to Entities:
LINQ Method syntax:
图片
//Querying with LINQ to Entities using (var context = newSchoolDBEntities()) { var L2EQuery = context.Students.where(s => s.StudentName == "Bill"); var student = L2EQuery.FirstOrDefault<Student>(); }
图片
LINQ Query syntax:
图片
using (var context = new SchoolDBEntities()) { var L2EQuery = from st in context.Students where st.StudentName == "Bill"select st; var student = L2EQuery.FirstOrDefault<Student>(); }
图片
Entity SQL:
图片
//Querying with Object Services and Entity SQL string sqlString = "SELECT VALUE st FROM SchoolDBEntities.Students " + "AS st WHERE st.StudentName == 'Bill'"; var objctx = (ctx as IObjectContextAdapter).ObjectContext; ObjectQuery<Student> student = objctx.CreateQuery<Student>(sqlString); Student newStudent = student.First<Student>(); //使用EntityDataReader using (var con = newEntityConnection("name=SchoolDBEntities")) { con.Open(); EntityCommand cmd = con.CreateCommand(); cmd.CommandText = "SELECT VALUE st FROM SchoolDBEntities.Students as st where st.StudentName='Bill'"; Dictionary<int, string> dict = newDictionary<int, string>(); using (EntityDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.CloseConnection)) { while (rdr.Read()) { int a = rdr.GetInt32(0); var b = rdr.GetString(1); dict.Add(a, b); } } }
图片
Native SQL:
图片
using (var ctx = newSchoolDBEntities()) { var studentName = ctx.Students.SqlQuery("Select studentid, studentname, standardId from Student where studentname='Bill'").FirstOrDefault<Student>(); }
图片
十二、追踪变更与抓久化场景
在联络景色下抓久化与脱机景色下抓久化
连机景色下抓久化,在归拢个DbContext中不需要放胆Entity,平直写入数据库
图片
脱机景色抓久化指读取和保存Entity在两个不同的DbContext中,Context2不知谈Entity的更新景色,是以必需奉告Context2刻下的Entity作念了何种更新。
图片
Context只在DbSet上追踪添加和删除
正确的添加和删除
图片
using (var context = new SchoolDBEntities()) { var studentList = context.Students.ToList<Student>(); //Perform create operation context.Students.Add(newStudent() { StudentName = "New Student" }); //Perform Update operationStudent studentToUpdate = studentList.Where(s => s.StudentName == "student1").FirstOrDefault<Student>(); studentToUpdate.StudentName = "Edited student1"; //Perform delete operation context.Students.Remove(studentList.ElementAt<Student>(0)); //Execute Inser, Update & Delete queries in the database context.SaveChanges(); }
图片
以下代码在List中添加和删除不起作用,唯独荣达有用
图片
using (var context = new SchoolDBEntities()) { var studentList = context.Students.ToList<Student>(); //Add student in list studentList.Add(new Student() { StudentName = "New Student" }); //Perform update operationStudent studentToUpdate = studentList.Where(s => s.StudentName == "Student1").FirstOrDefault<Student>(); studentToUpdate.StudentName = "Edited student1"; //Delete student from listif (studentList.Count > 0) studentList.Remove(studentList.ElementAt<Student>(0)); //SaveChanges will only do update operation not add and delete context.SaveChanges(); }
图片
脱机实体
脱机实体搞定要先附加到Context
图片
//disconnected entity graphStudent disconnectedStudent = newStudent() { StudentName = "New Student" }; disconnectedStudent.StudentAddress = newStudentAddress() { Address1 = "Address", City = "City1" }; using (var ctx = newSchoolDBEntities()) { //attach disconnected Student entity graph to new context instance - ctx ctx.Students.Attach(disconnectedStudent); // get DbEntityEntry instance to check the EntityState of specified entity var studentEntry = ctx.Entry(disconnectedStudent); var addressEntry = ctx.Entry(disconnectedStudent.StudentAddress); Console.WriteLine("Student EntityState: {0}",studentEntry.State); Console.WriteLine("StudentAddress EntityState: {0}",addressEntry.State); }
添增多个关系实体时与添加单个实体雷同,更新关系实体时需要追踪每个实体的景色。
十三 Entity Framework并发处理
添加RowVersion,类型为TimeStamp字段,在EDM中X修改并发属性为Fixed。EF更新实体时会先查验RowVersion,要是发现RowVersion不一致,则抛出DbUpdateConcurrencyException终点
图片
十四 缠绵加载、惰性加载与定向加载
缠绵加载:使用Include(),自动加载关联实体
图片
using (var context = new SchoolDBEntities()) { var res = (from s in context.Students.Include("Standard") where s.StudentName == "Student1" select s).FirstOrDefault<Student>(); }
图片
推论Sql
图片
SELECTTOP (1) [Extent1].[StudentID] AS [StudentID], [Extent1].[StudentName] AS [StudentName], [Extent2].[StandardId] AS [StandardId], [Extent2].[StandardName] AS [StandardName], [Extent2].[Description] AS [Description] FROM [dbo].[Student] AS [Extent1] LEFTOUTERJOIN [dbo].[Standard] AS [Extent2] ON [Extent1].[StandardId] = [Extent2].[StandardId] WHERE'Student1' = [Extent1].[StudentName]
图片
惰性加载:延伸加载对象关联的实体,用到时再加载,EF默许为LazyLoading
图片
using (var ctx = newSchoolDBEntities()) { //Loading students onlyIList<Student> studList = ctx.Students.ToList<Student>(); Student std = studList[0]; //Loads Student address for particular Student only (seperate SQL query) StudentAddress add = std.StudentAddress; }
图片
定向加载:Reference()和Collection() 智商
图片
using (var context = new SchoolDBEntities()) { //Loading students only IList<Student> studList = context.Students.ToList<Student>(); Student std = studList.Where(s => s.StudentID == 1).FirstOrDefault<Student>(); //Loads Standard for particular Student only (seperate SQL query) context.Entry(std).Reference(s => s.Standard).Load(); //Loads Courses for particular Student only (seperate SQL query) context.Entry(std).Collection(s => s.Courses).Load(); }
图片
十五:推论SQL
复返实体
using (var ctx = newSchoolDBEntities()) { //列名必需要Entity属性匹配 var studentList = ctx.Students.SqlQuery("Select * from Student").ToList<Student>(); }
复返非实体类型
using (var ctx = newSchoolDBEntities()) { //Get student name of string typestring studentName = ctx.Database.SqlQuery<string>("Select studentname from Student where studentid=1").FirstOrDefault<string>(); }
推论SQL高唱
图片
using (var ctx = new SchoolDBEntities()) { //Update commandint noOfRowUpdated = ctx.Database.ExecuteSqlCommand("Update student set studentname ='changed student by command' where studentid=1"); //Insert commandint noOfRowInserted = ctx.Database.ExecuteSqlCommand("insert into student(studentname) values('New Student')"); //Delete commandint noOfRowDeleted = ctx.Database.ExecuteSqlCommand("delete from student where studentid=1"); }
图片
转载于:https://www.cnblogs.com/wugu-ren/p/6855414.html
本站仅提供存储事业,统共骨子均由用户发布,如发现存害或侵权骨子,请点击举报。