EF | Entity framework
来源:互联网 发布:加索尔数据 编辑:程序博客网 时间:2024/06/11 15:34
1
首先在项目中添加一个ADO.NET实体数据模型,选好需要的表后,完成。然后它就会自动给我们应用了如下这些类库,下面是介绍这些类库的作用,及对edmx这个XML文件进行介绍
关于edmx文件的介绍 (如何查看这个Model1.edmx文件的XML文件呢?Model1.edmx-->(右键)打开方式-->XML(文本)编辑器)
展开来看看
<?xml version="1.0" encoding="utf-8"?><edmx:Edmx Version="3.0" xmlns:edmx="http://schemas.microsoft.com/ado/2009/11/edmx"> <!-- EF Runtime content --> <edmx:Runtime> <!-- SSDL content 【第一个节点:这是一个描述数据库的配置节】--> <edmx:StorageModels> <Schema Namespace="salesModel.Store" Provider="System.Data.SqlClient" ProviderManifestToken="2008" Alias="Self" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/11/edm/ssdl"> <EntityType Name="T_User"> <Key> <PropertyRef Name="Id" /> </Key> <Property Name="Id" Type="int" StoreGeneratedPattern="Identity" Nullable="false" /> <Property Name="UserName" Type="nvarchar" MaxLength="50" Nullable="false" /> <Property Name="Password" Type="varchar" MaxLength="50" Nullable="false" /> <Property Name="Email" Type="varchar" MaxLength="50" Nullable="false" /> <Property Name="Errors" Type="int" Nullable="false" /> <Property Name="Session" Type="nvarchar" MaxLength="50" Nullable="false" /> </EntityType> <EntityType Name="T_UserInfo"> <Key> <PropertyRef Name="Id" /> </Key> <Property Name="Id" Type="int" StoreGeneratedPattern="Identity" Nullable="false" /> <Property Name="UserName" Type="nvarchar" MaxLength="50" /> <Property Name="Name" Type="nvarchar" MaxLength="50" /> <Property Name="Age" Type="int" /> <Property Name="Gender" Type="int" /> <Property Name="Mobile" Type="varchar" MaxLength="50" /> <Property Name="Email" Type="varchar" MaxLength="50" /> <Property Name="Addres" Type="nvarchar" MaxLength="100" /> <Property Name="Remarks" Type="nvarchar" MaxLength="200" /> </EntityType> <EntityContainer Name="salesModelStoreContainer"> <EntitySet Name="T_User" EntityType="Self.T_User" Schema="dbo" store:Type="Tables" /> <EntitySet Name="T_UserInfo" EntityType="Self.T_UserInfo" Schema="dbo" store:Type="Tables" /> </EntityContainer> </Schema> </edmx:StorageModels> <!-- CSDL content 【第二个节点:这是一个描述实体的配置节】--> <edmx:ConceptualModels> <Schema Namespace="salesModel" Alias="Self" annotation:UseStrongSpatialTypes="false" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns="http://schemas.microsoft.com/ado/2009/11/edm"> <!--EntityType表示类 Nmae表示类的名字叫什么--> <EntityType Name="T_User"> <!--Key表示主键,PropertyRef Name="Id"表示主键为Id--> <Key> <PropertyRef Name="Id" /> </Key> <!--Property表示类中的属性,Name表示属性的名称,Type表示属性的类型,Nullable="false"表示这个字段不能为空,annotation:StoreGeneratedPattern="Identity"表示这个属性是自增的--> <Property Name="Id" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" /> <!--MaxLength表示UserName这个属性的最大长度值为50,FixedLength表示是否要固定长度,为true就表示要固定这个长度不变--> <Property Name="UserName" Type="String" MaxLength="50" FixedLength="false" Unicode="true" Nullable="false" /> <Property Name="Password" Type="String" MaxLength="50" FixedLength="false" Unicode="false" Nullable="false" /> <Property Name="Email" Type="String" MaxLength="50" FixedLength="false" Unicode="false" Nullable="false" /> <Property Name="Errors" Type="Int32" Nullable="false" /> <Property Name="Session" Type="String" MaxLength="50" FixedLength="false" Unicode="true" Nullable="false" /> </EntityType> <EntityType Name="T_UserInfo"> <Key> <PropertyRef Name="Id" /> </Key> <Property Name="Id" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" /> <Property Name="UserName" Type="String" MaxLength="50" FixedLength="false" Unicode="true" /> <Property Name="Name" Type="String" MaxLength="50" FixedLength="false" Unicode="true" /> <Property Name="Age" Type="Int32" /> <Property Name="Gender" Type="Int32" /> <Property Name="Mobile" Type="String" MaxLength="50" FixedLength="false" Unicode="false" /> <Property Name="Email" Type="String" MaxLength="50" FixedLength="false" Unicode="false" /> <Property Name="Addres" Type="String" MaxLength="100" FixedLength="false" Unicode="true" /> <Property Name="Remarks" Type="String" MaxLength="200" FixedLength="false" Unicode="true" /> </EntityType> <EntityContainer Name="salesEntities" annotation:LazyLoadingEnabled="true"> <EntitySet Name="T_User" EntityType="Self.T_User" /> <EntitySet Name="T_UserInfo" EntityType="Self.T_UserInfo" /> </EntityContainer> </Schema> </edmx:ConceptualModels> <!-- C-S mapping content 【第三个节点:这是一个描述数据库与实体之间的关系映射的配置节】--> <edmx:Mappings> <Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2009/11/mapping/cs"> <EntityContainerMapping StorageEntityContainer="salesModelStoreContainer" CdmEntityContainer="salesEntities"> <EntitySetMapping Name="T_User"> <EntityTypeMapping TypeName="salesModel.T_User"> <MappingFragment StoreEntitySet="T_User"> <!--Name="Id"表示实体里面的属性名Id ColumnName="Id"表示数据库表中的Id属性,即实体中的Id对应数据库表中的Id列--> <ScalarProperty Name="Id" ColumnName="Id" /> <ScalarProperty Name="UserName" ColumnName="UserName" /> <ScalarProperty Name="Password" ColumnName="Password" /> <ScalarProperty Name="Email" ColumnName="Email" /> <ScalarProperty Name="Errors" ColumnName="Errors" /> <ScalarProperty Name="Session" ColumnName="Session" /> </MappingFragment> </EntityTypeMapping> </EntitySetMapping> <EntitySetMapping Name="T_UserInfo"> <EntityTypeMapping TypeName="salesModel.T_UserInfo"> <MappingFragment StoreEntitySet="T_UserInfo"> <ScalarProperty Name="Id" ColumnName="Id" /> <ScalarProperty Name="UserName" ColumnName="UserName" /> <ScalarProperty Name="Name" ColumnName="Name" /> <ScalarProperty Name="Age" ColumnName="Age" /> <ScalarProperty Name="Gender" ColumnName="Gender" /> <ScalarProperty Name="Mobile" ColumnName="Mobile" /> <ScalarProperty Name="Email" ColumnName="Email" /> <ScalarProperty Name="Addres" ColumnName="Addres" /> <ScalarProperty Name="Remarks" ColumnName="Remarks" /> </MappingFragment> </EntityTypeMapping> </EntitySetMapping> </EntityContainerMapping> </Mapping> </edmx:Mappings> </edmx:Runtime> <!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) --> <Designer xmlns="http://schemas.microsoft.com/ado/2009/11/edmx"> <Connection> <DesignerInfoPropertySet> <DesignerProperty Name="MetadataArtifactProcessing" Value="EmbedInOutputAssembly" /> </DesignerInfoPropertySet> </Connection> <Options> <DesignerInfoPropertySet> <DesignerProperty Name="ValidateOnBuild" Value="true" /> <DesignerProperty Name="EnablePluralization" Value="false" /> <DesignerProperty Name="IncludeForeignKeysInModel" Value="true" /> <DesignerProperty Name="UseLegacyProvider" Value="true" /> <DesignerProperty Name="CodeGenerationStrategy" Value="无" /> </DesignerInfoPropertySet> </Options> <!-- Diagram content (shape and connector positions) --> <Diagrams></Diagrams> </Designer></edmx:Edmx>
我们在来看看Model1.Context.cs这个上下文容器类
//------------------------------------------------------------------------------// <auto-generated>// 此代码是根据模板生成的。//// 手动更改此文件可能会导致应用程序中发生异常行为。// 如果重新生成代码,则将覆盖对此文件的手动更改。// </auto-generated>//------------------------------------------------------------------------------namespace WebAppEF{ using System; using System.Data.Entity; using System.Data.Entity.Infrastructure; public partial class salesEntities : DbContext { /// <summary> /// 用来初始化ado.net连接对象 /// </summary> public salesEntities() : base("name=salesEntities")//这里调用父类的带一个参数的构造函数,传递的"name=salesEntities"值就表示告诉我们 去web.config配置文件中 找到<connectionStrings>这个节点下name为salesEntities的这个配置节点,用它来初始化我们的ado.net连接对象 { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { throw new UnintentionalCodeFirstException(); } //下面我们来看看这个DbSet<T> 这个泛型类。以下是这个类的定义: // public class DbSet<TEntity> : DbQuery<TEntity>, IDbSet<TEntity>, IQueryable<TEntity>, IEnumerable<TEntity>, IQueryable, IEnumerable, IInternalSetAdapter where TEntity: class //根据DbSet<T>的定义我们可以看到这个泛型类是继承了 IQueryable<TEntity>, IEnumerable<TEntity>, IQueryable, IEnumerable 等接口的 //而在System.Linq命名空间下的Queryable类中,为IQueryable<TEntity> 这个泛型接口扩展了很多方法,如:Where(),Any(),Count(),OrderBy(),,ThenBy(),Groupby(),Join(),Select(),Find(),First(),Last(),FirstOrDefault(),First(),Find(),Single(),Skip(),Take()等方法。而DbSet<T>这个泛型类又是实现了这个IQueryable<TEntity> 接口的,所以DbSet<T>这个泛型类的对象是可以使用IQueryable<TEntity> 接口中的这些扩展方法的。通过这些泛型方法,我们进行数据的相关查询。 //我们在看看这个DbSet<T>泛型类的定义,我们看到它是继承一个 DbQuery<TEntity>的类。而这个DbQuery<TEntity>类也同样实现了Queryable<TEntity>这个泛型接口,所以DbQuery<TEntity>这个泛型类的对象同样也是可以使用Queryable<TEntity>这个泛型接口中的扩展方法的。 //所以综上所述:DbSet<T>这个泛型类的作用就是:用于提供SQO方法,结合程序员写Lambda表达式进行数据的相关查询 public DbSet<T_User> T_User { get; set; } public DbSet<T_UserInfo> T_UserInfo { get; set; } }}
EF的查询原理
我们要特别留意这个代理类对象中的State属性的值,它的值是一个枚举类型的值,它的值的作用就告诉EF,生成什么类型的SQL语句(如:insert,update,Delete)
当我们调用db.SaveChanges()方法的时候,就会通知EF容器遍历当前EF容器中所有State为非Detached的代理类对象
再根据代理类对象的State的值,生成相应的Sql语句发送给DB执行,例如
当State=EntityState.Added 的时候 ,则生成 Insert 的SQL语句
当State=EntityState.Deleted 的时候 ,则生成 Delete的SQL语句
当State=EntityState.Modified 的时候 ,则生成 Update的SQL语句
当数据从数据库表中刚查询出来的时候State的状态为 State=EntityState.Unchanged 表示没有改动过。
当State=EntityState.Detached 的时候,表示 虽然代理类在EF容器的内部,但是你不需要管我,直接忽略我
我们在来了解一下在EF中,做新增数据的一些注意知识点(获取新增数据的Id)
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;namespace WebAppEF{ public partial class WebForm1 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { salesEntities db = new salesEntities(); T_UserInfo model=new T_UserInfo(){ Addres="123", Age=25, Name="张三", Gender=1, Email="123@qq.com", Mobile="18620088006", UserName="小张", Remarks="ddd"}; db.T_UserInfo.Add(model); db.SaveChanges(); Response.Write(model.Id) //这里会打印出插入的那条数据的最新Id } }}
当用户在做这一条数据插入的时候,
当 salesEntities db = new salesEntities();就表示创建了EF容器类的对象。
当写完 T_UserInfo model=new T_UserInfo(){ Addres="123", Age=25, Name="张三", Gender=1, Email="123@qq.com", Mobile="18620088006", UserName="小张", Remarks="ddd"}; 这条语句的时候,这个对象还是在应用程序的内存中,与EF还没有联系,
当执行db.T_UserInfo.Add(model);的时候, 这条model对象已经加入到EF容器类中。
在EF容器类中,将这个对象包装成一个代理类对象 (注意此时这个代理类对象里面有一个State=Addend属性,而刚刚我创建model 这条对象的时候并没有写Id这个属性(因为Id是一个自增值),可是它这里将自己添加了一个Id,并初始值为0)
当我们调用db.SaveChanges();的时候,就会通知EF容器遍历当前EF容器中所有State为非Detached的代理类对象,正好在这里找到一个State=Added的代理类对象,然后就生成了Insert的SQL语句,发给DB执行。
我们同过SQL server Profiler监控工具,发现这条SQL语句是这样的
exec sp_executesql N'insert [dbo].[T_UserInfo]([UserName], [Name], [Age], [Gender], [Mobile], [Email], [Addres], [Remarks])values (@0, @1, @2, @3, @4, @5, @6, @7)select [Id]from [dbo].[T_UserInfo]where @@ROWCOUNT > 0 and [Id] = scope_identity()',N'@0 nvarchar(50),@1 nvarchar(50),@2 int,@3 int,@4 varchar(50),@5 varchar(50),@6 nvarchar(100),@7 nvarchar(200)',@0=N'小张',@1=N'张三',@2=25,@3=1,@4='18620997006',@5='123@qq.com',@6=N'123',@7=N'ddd'
注意,这条SQL 存储过程执行插入语句,语句中并没有包含代理类中的Id属性的。(因为T_UserInfo表中的Id字段为自增字段,不需要赋值。所以这里不要包含),但是我们插入了一条新的数据后,我们怎么知道插入的那条数据的Id是多少呢?
当DB执行完这条插入语句的存储过程的时候,马上又执行了以下查询语句:
select [Id]
from [dbo].[T_UserInfo]where @@ROWCOUNT > 0 and [Id] = sscope_identity()....
其中scope_identity()表示获取最后一条数据的标识值。 通过这条语句 就将刚刚插入进去的那条数据的Id 就拿到了。然后在通过Ado.net将这个Id交给EF,EF在将这个代理类中的Id的值从0改为从数据库返回的新值。
所以当一条数据成功插入后,我们就可以用model.Id 来得到这条新增的数据的Id值。
注意点
<configSections> <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> </configSections> <connectionStrings> <add name="salesEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=sales;persist security info=True;user id=sa;password=123456;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" /> </connectionStrings> <entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> <parameters> <parameter value="v11.0" /> </parameters> </defaultConnectionFactory> </entityFramework>
- EF | Entity framework
- 【Entity Framework】EF初识
- Linq与EF(Entity Framework)
- ADO.NET Entity Framework(EF)
- Entity Framework(EF)数据查询
- Entity Framework 5.0系列之EF概览
- Entity Framework(EF)知识整理
- Entity Framework 5.0系列之EF概览
- Entity Framework 5.0系列之EF概览
- Entity Framework(实体框架 EF)
- 初学实体框架EF(Entity Framework)
- EF Mapping2 Entity Framework Fluent API
- EF Mapping Entity Framework Fluent API
- EF Mapping Entity Framework Fluent API
- Entity Framework (EF)/Linq To entity/ ESQL(entity sql)区别 ADO.NET Entity Framework:来自微软官方的ORM框架
- EF(Asp.Net Entity Framework)做为数据模型框架 的应用
- 对ADO.NET Entity Framework( EF)的理解
- Entity Framework 学习初级篇1--EF基本概况
- 短文本分类
- Ofbiz 容器中的帮助类对象
- android应用完全退出,并且从最近运行程序以及系统正在运行列表中完全抹除。
- UILabel,文字中间划横线
- [MSCHART]如何使用MSCHART实现雷达图
- EF | Entity framework
- 小胖说事41-----iOS中在UILabel显示不同的字体和颜色,增加下划线和删除线
- 基于强类型的客户端异步刷新调用
- 为啥用到了EventBus?
- 对hibernateTemplate 类的 方法中使用 new HibernateCallback()接口形象doInHibernate()方法的理解
- Windows下exe和dll文件怎么判定自己该链接何种版本的c运行时库的研究
- iOS访问webservice
- 位图法之排除相同的数
- ccpc Pick The Sticks(dp特殊处理)