Entity Framework 基础知识走马观花
本文目录:
一、EF中的edmx文件
1.1 emdx文件本质:一个XML文件
(1)通过选择以XML方式打开edmx文件,我们可以可以清楚地看到,edmx模型文件本质就是一个XML文件;
(2)可以清楚地看到,edmx模型文件是一个XML文件,其中定义了三大组成部分,这三大组成部分构成了所谓的ORM(对象关系映射);
(3)再通过解决方案管理器分析edmx模型文件,其包含了三个子文件:
①第一个是xxx.Context.tt,这个首先是一个T4的模板文件,它生成了我们这个模型的上下文类;
public partial class LearnEntities : DbContext
{
public LearnEntities()
: base("name=LearnEntities")
{
} protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
} public DbSet<T_Class> T_Class { get; set; }
public DbSet<T_Message> T_Message { get; set; }
public DbSet<T_Person> T_Person { get; set; }
}
②第二个是设计器部分,它定义了模型关系图的元数据,比如每个类图的宽度多少,在图中的坐标(X、Y轴)等;
<edmx:Diagrams>
<Diagram DiagramId="edad56670ede49c5ae2e343c9da730f1" Name="关系图1">
<EntityTypeShape EntityType="LearnModel.T_Class" Width="1.5" PointX="0.75" PointY="1.75" />
<EntityTypeShape EntityType="LearnModel.T_Message" Width="1.5" PointX="5.25" PointY="" />
<EntityTypeShape EntityType="LearnModel.T_Person" Width="1.5" PointX="" PointY="1.25" />
<AssociationConnector Association="LearnModel.FK_T_Person_T_Class" />
<AssociationConnector Association="LearnModel.FK_T_Message_T_Person1" />
<AssociationConnector Association="LearnModel.FK_T_Message_T_Person2" />
</Diagram>
</edmx:Diagrams>
③第三个就是数据库表中所对应的实体类对象,它也是一个T4模板文件,对应了所有选择的数据库表:
public partial class T_Class
{
public T_Class()
{
this.T_Person = new HashSet<T_Person>();
} public int Id { get; set; }
public string Name { get; set; } public virtual ICollection<T_Person> T_Person { get; set; }
}
1.2 emdx组成部分:SSDL、CSDL、C-S Mapping
(1)SSDL
它定义了数据库中所对应的表的定义,也可以称为存储模型:
<edmx:StorageModels>
<Schema Namespace="LearnModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl">
<EntityContainer Name="LearnModelStoreContainer">
<EntitySet Name="T_Class" EntityType="LearnModel.Store.T_Class" store:Type="Tables" Schema="dbo" />
<EntitySet Name="T_Message" EntityType="LearnModel.Store.T_Message" store:Type="Tables" Schema="dbo" />
<EntitySet Name="T_Person" EntityType="LearnModel.Store.T_Person" store:Type="Tables" Schema="dbo" />
<AssociationSet Name="FK_T_Message_T_Person1" Association="LearnModel.Store.FK_T_Message_T_Person1">
<End Role="T_Person" EntitySet="T_Person" />
<End Role="T_Message" EntitySet="T_Message" />
</AssociationSet>
<AssociationSet Name="FK_T_Message_T_Person2" Association="LearnModel.Store.FK_T_Message_T_Person2">
<End Role="T_Person" EntitySet="T_Person" />
<End Role="T_Message" EntitySet="T_Message" />
</AssociationSet>
<AssociationSet Name="FK_T_Person_T_Class" Association="LearnModel.Store.FK_T_Person_T_Class">
<End Role="T_Class" EntitySet="T_Class" />
<End Role="T_Person" EntitySet="T_Person" />
</AssociationSet>
</EntityContainer>
<EntityType Name="T_Class">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
<Property Name="Name" Type="nvarchar" MaxLength="" />
</EntityType>
<EntityType Name="T_Message">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
<Property Name="Title" Type="nvarchar" Nullable="false" MaxLength="" />
<Property Name="Message" Type="nvarchar(max)" Nullable="false" />
<Property Name="NickName" Type="nvarchar" Nullable="false" MaxLength="" />
<Property Name="IsAnonymous" Type="bit" Nullable="false" />
<Property Name="IPAddress" Type="nvarchar" Nullable="false" MaxLength="" />
<Property Name="PostDate" Type="datetime" Nullable="false" />
<Property Name="PostManId" Type="int" Nullable="false" />
<Property Name="ReceiveManId" Type="int" Nullable="false" />
</EntityType>
<EntityType Name="T_Person">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
<Property Name="Name" Type="nvarchar" Nullable="false" MaxLength="" />
<Property Name="Age" Type="int" Nullable="false" />
<Property Name="Email" Type="nvarchar" Nullable="false" MaxLength="" />
<Property Name="ClassId" Type="int" Nullable="false" />
</EntityType>
<Association Name="FK_T_Message_T_Person1">
<End Role="T_Person" Type="LearnModel.Store.T_Person" Multiplicity="" />
<End Role="T_Message" Type="LearnModel.Store.T_Message" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="T_Person">
<PropertyRef Name="Id" />
</Principal>
<Dependent Role="T_Message">
<PropertyRef Name="PostManId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_T_Message_T_Person2">
<End Role="T_Person" Type="LearnModel.Store.T_Person" Multiplicity="" />
<End Role="T_Message" Type="LearnModel.Store.T_Message" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="T_Person">
<PropertyRef Name="Id" />
</Principal>
<Dependent Role="T_Message">
<PropertyRef Name="ReceiveManId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_T_Person_T_Class">
<End Role="T_Class" Type="LearnModel.Store.T_Class" Multiplicity="" />
<End Role="T_Person" Type="LearnModel.Store.T_Person" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="T_Class">
<PropertyRef Name="Id" />
</Principal>
<Dependent Role="T_Person">
<PropertyRef Name="ClassId" />
</Dependent>
</ReferentialConstraint>
</Association>
</Schema>
</edmx:StorageModels>
例如,我们可以通过下面的一个代码片段来看看它在说明什么?
<EntityType Name="T_Person">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
<Property Name="Name" Type="nvarchar" Nullable="false" MaxLength="" />
<Property Name="Age" Type="int" Nullable="false" />
<Property Name="Email" Type="nvarchar" Nullable="false" MaxLength="" />
<Property Name="ClassId" Type="int" Nullable="false" />
</EntityType>
是不是跟我们在MSSQL中所进行的数据表设计差不多?指定主键、指定字段的类型、是否为NULL,最大长度等等;
(2)CSDL
它定义了EF模型中与SSDL对应的实体类对象的定义,这里C代表Concept,即概念模型;
<edmx:ConceptualModels>
<Schema Namespace="LearnModel" Alias="Self" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
<EntityContainer Name="LearnEntities" annotation:LazyLoadingEnabled="true">
<EntitySet Name="T_Class" EntityType="LearnModel.T_Class" />
<EntitySet Name="T_Message" EntityType="LearnModel.T_Message" />
<EntitySet Name="T_Person" EntityType="LearnModel.T_Person" />
<AssociationSet Name="FK_T_Person_T_Class" Association="LearnModel.FK_T_Person_T_Class">
<End Role="T_Class" EntitySet="T_Class" />
<End Role="T_Person" EntitySet="T_Person" />
</AssociationSet>
<AssociationSet Name="FK_T_Message_T_Person1" Association="LearnModel.FK_T_Message_T_Person1">
<End Role="T_Person" EntitySet="T_Person" />
<End Role="T_Message" EntitySet="T_Message" />
</AssociationSet>
<AssociationSet Name="FK_T_Message_T_Person2" Association="LearnModel.FK_T_Message_T_Person2">
<End Role="T_Person" EntitySet="T_Person" />
<End Role="T_Message" EntitySet="T_Message" />
</AssociationSet>
</EntityContainer>
<EntityType Name="T_Class">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Type="Int32" Name="Id" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
<Property Type="String" Name="Name" MaxLength="" FixedLength="false" Unicode="true" />
<NavigationProperty Name="T_Person" Relationship="LearnModel.FK_T_Person_T_Class" FromRole="T_Class" ToRole="T_Person" />
</EntityType>
<EntityType Name="T_Message">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Type="Int32" Name="Id" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
<Property Type="String" Name="Title" Nullable="false" MaxLength="" FixedLength="false" Unicode="true" />
<Property Type="String" Name="Message" Nullable="false" MaxLength="Max" FixedLength="false" Unicode="true" />
<Property Type="String" Name="NickName" Nullable="false" MaxLength="" FixedLength="false" Unicode="true" />
<Property Type="Boolean" Name="IsAnonymous" Nullable="false" />
<Property Type="String" Name="IPAddress" Nullable="false" MaxLength="" FixedLength="false" Unicode="true" />
<Property Type="DateTime" Name="PostDate" Nullable="false" Precision="" />
<Property Type="Int32" Name="PostManId" Nullable="false" />
<Property Type="Int32" Name="ReceiveManId" Nullable="false" />
<NavigationProperty Name="T_Person" Relationship="LearnModel.FK_T_Message_T_Person1" FromRole="T_Message" ToRole="T_Person" />
<NavigationProperty Name="T_Person1" Relationship="LearnModel.FK_T_Message_T_Person2" FromRole="T_Message" ToRole="T_Person" />
</EntityType>
<EntityType Name="T_Person">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Type="Int32" Name="Id" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
<Property Type="String" Name="Name" Nullable="false" MaxLength="" FixedLength="false" Unicode="true" />
<Property Type="Int32" Name="Age" Nullable="false" />
<Property Type="String" Name="Email" Nullable="false" MaxLength="" FixedLength="false" Unicode="true" />
<Property Type="Int32" Name="ClassId" Nullable="false" />
<NavigationProperty Name="T_Class" Relationship="LearnModel.FK_T_Person_T_Class" FromRole="T_Person" ToRole="T_Class" />
<NavigationProperty Name="T_Message" Relationship="LearnModel.FK_T_Message_T_Person1" FromRole="T_Person" ToRole="T_Message" />
<NavigationProperty Name="T_Message1" Relationship="LearnModel.FK_T_Message_T_Person2" FromRole="T_Person" ToRole="T_Message" />
</EntityType>
<Association Name="FK_T_Person_T_Class">
<End Type="LearnModel.T_Class" Role="T_Class" Multiplicity="" />
<End Type="LearnModel.T_Person" Role="T_Person" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="T_Class">
<PropertyRef Name="Id" />
</Principal>
<Dependent Role="T_Person">
<PropertyRef Name="ClassId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_T_Message_T_Person1">
<End Type="LearnModel.T_Person" Role="T_Person" Multiplicity="" />
<End Type="LearnModel.T_Message" Role="T_Message" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="T_Person">
<PropertyRef Name="Id" />
</Principal>
<Dependent Role="T_Message">
<PropertyRef Name="PostManId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_T_Message_T_Person2">
<End Type="LearnModel.T_Person" Role="T_Person" Multiplicity="" />
<End Type="LearnModel.T_Message" Role="T_Message" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="T_Person">
<PropertyRef Name="Id" />
</Principal>
<Dependent Role="T_Message">
<PropertyRef Name="ReceiveManId" />
</Dependent>
</ReferentialConstraint>
</Association>
</Schema>
</edmx:ConceptualModels>
当然,我们再通过一个代码片段来看看在概念模型中是如何定义的?
<EntityType Name="T_Person">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Type="Int32" Name="Id" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
<Property Type="String" Name="Name" Nullable="false" MaxLength="" FixedLength="false" Unicode="true" />
<Property Type="Int32" Name="Age" Nullable="false" />
<Property Type="String" Name="Email" Nullable="false" MaxLength="" FixedLength="false" Unicode="true" />
<Property Type="Int32" Name="ClassId" Nullable="false" />
<NavigationProperty Name="T_Class" Relationship="LearnModel.FK_T_Person_T_Class" FromRole="T_Person" ToRole="T_Class" />
<NavigationProperty Name="T_Message" Relationship="LearnModel.FK_T_Message_T_Person1" FromRole="T_Person" ToRole="T_Message" />
<NavigationProperty Name="T_Message1" Relationship="LearnModel.FK_T_Message_T_Person2" FromRole="T_Person" ToRole="T_Message" />
</EntityType>
在CSDL中,大部分都与SSDL中所对应的一致,但是我们发现多了一些属性。例如:NavigationProperty 导航属性,因为T_Person表与T_Class、T_Message表都存在一对一或一对多的关系(即存在外键),因此在EF模型所生成的对象实体中,加入了外键所在实体的导航属性。
(3)C-S Mapping
它是一个映射关系,它将SSDL与CSDL对应了起来,因此我们在用EF操作实体类时才可以正确地生成对相应数据表的SQL语句。
<EntitySetMapping Name="T_Person">
<EntityTypeMapping TypeName="LearnModel.T_Person">
<MappingFragment StoreEntitySet="T_Person">
<ScalarProperty Name="ClassId" ColumnName="ClassId" />
<ScalarProperty Name="Email" ColumnName="Email" />
<ScalarProperty Name="Age" ColumnName="Age" />
<ScalarProperty Name="Name" ColumnName="Name" />
<ScalarProperty Name="Id" ColumnName="Id" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
</EntityContainerMapping>
可以看出,这里将SSDL中的T_Person与CSDL中的LearnModel.T_Person对应了起来,当然还将他们各自的属性进行了一一对应。
二、EF中的代理类对象
2.1 代理模式初探
通过上面的图片,我们可以看到,通过增加代理类B来解耦A与C之间的调用,这样可以封装原来C调用A的一些相关细节,转换成C直接调用B中封装后的代理方法,则等同于访问A。在实际应用中,例如对于WebService的远程调用时,如果我们使用添加Web引用的方式,那么WebService会为我们自动生成代理类,我们所有的交互都只是和代理类进行的,而没有直接和服务提供者进行。
代理模式:可以看看园友程兴亮的一篇文章《极速理解设计模式之代理模式》
2.2 EF中的代理应用
(1)我们首先有下面这样一段代码,它要进行的是一个简单的修改操作:
static void Edit()
{
// 下面返回的是一个Person类的代理类对象
T_Person person = db.T_Person.FirstOrDefault(p => p.Id == );
Console.WriteLine("Before update:{0}", person.ToString());
// 此时操作的也只是Person类的代理类对象,同时标记此属性为已修改
person.Name = "周旭龙";
person.Email = "edisonchou7@cuit.edu.cn";
person.Age = ;
// 此时EF上下文会检查容器内部所有的对象,
// 找到标记为修改的对象属性生成对应的修改SQL语句
db.SaveChanges();
Console.WriteLine("Update Successfully~~");
}
(2)通过分析这段代码,我们知道要进行一个修改操作,需要经过三个步凑:第一是查询到要修改的那一行,然后进行修改操作赋值,最后提交修改操作。(当然,这是官方推荐的修改操作步凑,你也可以不经过查询而直接修改,这需要利用到DbEntityEntry)那么,为什么要经过这几个步凑呢?
①我们首先来看看第一步:查询
db.T_Person.FirstOrDefault(p => p.Id == 11);
在实际开发中,我们的应用程序不会直接和数据库打交道,而是和EF数据上下文中的代理类打交道。首先,通过查询操作数据库返回了一行数据,EF上下文将其接收并将其“包装”起来,于是就有了代理类。在代理类中,真实的实体类对象被封装了起来,并且在代理类中为每个属性都设置了一个标志,用来标识其状态(是否被修改)。而我们在程序中所获得的数据,都是从代理类中返回的。
②再来看看第二步:修改
person.Name = "周旭龙";
当执行完修改操作之后,代理类中对应字段的标志会被修改,例如我们这里修改了Name属性,那么其对应的标志就会由false变为true。虽然只是变了一个标志位,但是却对EF生成SQL语句产生了重大影响。如果我们只修改了一个属性,那么其生成的SQL语句只会有一个Update ** Set Name='***'。
③最后来看看第三步:提交
db.SaveChanges();
当SaveChanges方法触发时,EF上下文会遍历代理类对象中的状态标志,如果发现有修改的(即为True)则将其加入生成的SQL语句中。这里,因为Name被修改了,所以在生成的SQL语句中会将Name加入,而其他未修改的则不会加入。
我们也可以通过SQLServer Profiler来查看EF所生成的SQL语句:
三、EF中的延迟加载与即时加载
3.1 浅谈延迟加载
所谓延迟加载,就是只有在我们需要数据的时候才去数据库读取加载它。
在Queryable类中的扩展方法中,Where方法就是一个典型的延迟加载案例。在实际的开发中,我们往往会使用一些ORM框架例如EF去操作数据库,Where方法的使用则是每次调用都只是在后续生成SQL语句时增加一个查询条件,EF无法确定本次查询是否已经添加结束,所以没有办法木有办法在每个Where方法执行的时候确定最终的SQL语句,只能返回一个DbQuery对象,当使用到这个DbQuery对象的时候,才会根据所有条件生成最终的SQL语句去查询数据库。
(1)针对条件的延迟加载
DbQuery<T_Person> query = db.T_Person.Where(p => p.Id == ).OrderBy(p => p.Age) as DbQuery<T_Person>;
// 用的时候才去加载:根据之前的条件生成SQL语句访问数据库
T_Person person = query.FirstOrDefault();
通过SQLServer Profiler调试跟踪,当执行完第一行代码时,是没有进行对数据库的查询操作的。而当执行到第二行的FirstOrDefault()方法时,EF才根据前面的条件生成了查询SQL语句去加载数据。
(2)针对外键的延迟加载
首先,我们有这样两张表,他们是1:N的关系;其中ClassId是T_Person的外键;
其次,在EF所生成的实体对象中,在T_Person的代码中会有一个T_Class的对象属性;因为一个T_Person对应一个T_Class;
public partial class T_Person
{
public T_Person()
{
this.T_Message = new HashSet<T_Message>();
this.T_Message1 = new HashSet<T_Message>();
} public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
public int ClassId { get; set; } public virtual T_Class T_Class { get; set; }
}
最后,在实际开发中,我们有如下一段代码:
IQueryable<T_Person> dbQuery = db.T_Person.Where(p => p.ClassId == );
T_Person person = dbQuery.FirstOrDefault();
Console.WriteLine(person.T_Class.Name);
通过调试我们可以发现,在执行最后一段代码输出Person对象所属班级的信息之前,都没有对Class进行查询。而在执行到最后一句时,才去数据库查询所对应的Class信息;
3.2 浅谈即时加载
所谓即时加载,就是在加载数据时就把该对象相关联的其它表的数据一起加载到内存对象中去。
在Queryable类中的扩展方法中,ToList()方法就是一个典型的即时加载案例。与延迟加载相对应,在开发中如果使用ToList()方法,EF会根据方法中的条件自动生成SQL语句,然后立即与数据库进行交互获取查询结果,并加载到内存中去。
(1)例如,我们有以下一段代码,在执行到第一句的ToList()方法时,EF就立即对数据库发起访问,并将结果记载到了内存中,最后将personList指向了这块记录在堆中的地址;
List<T_Person> personList = db.T_Person.Where(p => p.ClassId == ).ToList();
personList.ForEach(p => Console.WriteLine(p.ToString()));
(2)这时候,如果我们再想对查询到的结果进行排序,我们该怎么写?是不是写出了以下的代码:
List<T_Person> personList = db.T_Person.Where(p => p.ClassId == ).ToList().OrderBy(p => p.Name).ToList();
personList.ForEach(p => Console.WriteLine(p.ToString()));
这时我们发现,当ToList()之后,OrderBy()方法就没有对SQL语句进行调整,也没有再对数据库发起请求了。因为,这里的OrderBy()方法是对内存中的数据进行的排序,而不是和前面的Where()方法一起拼接成SQL语句。
3.3 使用Include提高查询效率
前面我们看到了延迟加载在EF中被广泛应用,但是延迟加载对于外键的加载也存在不足:那就是每次调用外键实体都会去查数据库。
(1)我们来看看下面一段代码,它的作用是通过每个班级查询所对应的所有学生信息:
IQueryable<T_Class> classQuery = db.T_Class;
foreach (T_Class c in classQuery)
{
Console.WriteLine(c.Id + "-" + c.Name + ":");
ICollection<T_Person> pList = c.T_Person;
foreach (T_Person p in pList)
{
Console.WriteLine(p.Id + "-" + p.Name);
}
}
其显示结果如下图所示:
(2)通过SQLServer Profiler跟踪,可以发现,每次调用外键实体属性时都会对数据库发出一起查询请求,从下图也可以看出,总共发出了接近10个请求;
(3)但是,EF也做了一个小优化:对于相同外键的加载请求,只会执行一次;例如,这里存在多个ClassId=1的Person记录,因此它们都只会执行一次即可;
(4)虽然EF做了一些优化,但是有木有一种方法能够让我们只通过一次请求就获取所有的信息呢?在SQL语句中,我们可以通过一个超级简单的连接查询就可以实现,那么在EF中呢如何实现呢?还好,微软早就想到了这一点,为我们提供了一个Include方法。我们可以对上面的代码段进行修改,得到下面的代码:
IQueryable<T_Class> classQuery = db.T_Class.Include("T_Person");
foreach (T_Class c in classQuery)
{
Console.WriteLine("班级:" + c.Id + " " + c.Name + ":");
ICollection<T_Person> pList = c.T_Person;
foreach (T_Person p in pList)
{
Console.WriteLine(p.Id + "-" + p.Name);
}
}
这下程序在执行到Include方法时,便会与T_Person表进行一个连接查询,将连接查询到的T_Person部分数据存入T_Class的T_Person属性中,也就是都存入了内存中,后面再次访问外键实体只需要从内存中读取而不用再发出多个数据库查询请求了。
Include方法跟ToList方法一样,也是即时加载类型的一种具体方法,其本质是生成连接查询的SQL语句。从整体来看,通过Include将以空间换取效率,在某些具体的应用场合可以适当使用。
参考资料
(1)陈少鑫,《EF贪婪加载与延迟加载的选择和使用》:http://www.cnblogs.com/chenshao/p/4169210.html
(2)强子,《解析ASP.NET MVC开发方式之EF延迟加载》:http://www.cnblogs.com/qq731109249/p/3502874.html
(3)Liam Wang,《ASP.NET MVC小牛之路:使用EF》:http://www.cnblogs.com/willick/p/3304534.html
Entity Framework 基础知识走马观花的更多相关文章
- .NET Framework基础知识总结
之前给大家总结了java的面试几次技巧总结,同学们看了觉得还是不错,能够得到大家的认可,感觉还是挺不错的.现在又有同学来想小编索要.NET面试的总结了,好吧.谁让小编这么好呢!以下是.NET面试之框架 ...
- ADO.NET 之 Entity Framework 基础
Entity Framework(EF)是使用直接映射到应用程序中业务对象的对象模型于关系数据库进行交互.它没有将数据视为行和列的集合,而是将其视为强类型对象(成为实体)的集合. 术语:LinQ to ...
- Entity Framework基础01
学习了ADO.NET的相关知识,掌握了它对数据库表的基本操作,但是实际在开发项目应用中微软为我们开发ef这个ORM,使用它可以很方便的利用ADO.NET来操作DBMS,使得我们开发项目的着重点放在业务 ...
- Entity Framework 基础
在忙碌中渡过了5,6,7 月份,现在些抽点时间对Entity Framework的使用做一些基础的回忆. Entity Framework 是什么? Entity Framework(EF)和我们所熟 ...
- Entity Framework 基础操作(1)
EF是微软推出的官方ORM框架,默认防注入可以配合LINQ一起使用,更方便开发人员. 首先通过SQLSERVER现在有的数据库类生产EF 右键->添加->新建项,选择AOD.NET实体数据 ...
- .Net Framework基础知识
.net常识 .net framework是微软为开发应用程序而创建的一个富有革命性的新平台: .net可以用来开发windows应用程序,web应用程序,web服务和其它各种类型的程序. . ...
- Entity Framework小知识
记录在使用EF中使用的技巧,以备查阅. 1.当需要查询一个列总和的时候,如果列是允许NULL或者未查到信息的时候,想要返回的是0 而非NULL时 db.表名.Sum(p=> (decimal?) ...
- .NET Framework基础知识(五)(转载)
.程序集:是 .NET Framework 应用程序的构造块:程序集构成了部署.版本控制.重复使用.激活范围控制和 安全权限的基本单元. .程序集的优点:版本控制问题.最终解决DLL冲突 .程序集分为 ...
- .NET Framework基础知识(四)(转载)
.反射:是编程的读取与类型相关联的元数据的行为.通过读取元数据,可以了解它是什么类型以及类型的成员. 比如类中的属性,方法,事件等.所属命名空间System.Reflection. 例:using S ...
随机推荐
- 用goto做异常处理
http://www.cnblogs.com/trying/archive/2012/06/25/2863753.html 今天在CSDN上看到的关于错误返回值的讨论,感觉非常有趣. 从中可以看出被教 ...
- 基于.NET平台常用的框架整理
自从学习.NET以来,优雅的编程风格,极度简单的可扩展性,足够强大开发工具,极小的学习曲线,让我对这个平台产生了浓厚的兴趣,在工作和学习中也积累了一些开源的组件,就目前想到的先整理于此,如果再想到,就 ...
- axure的一些注意事项
1. 不要轻易用中继器的 载入时 事件, 感觉存在bug 2. 元件在显示和隐藏的动画过程中,不要去取他的x,y值,有几率会取成0,也不要去获取它的尺寸,只有在动画完成后才能获得 3. 装着一个中继器 ...
- fullPage.js学习笔记
中秋节,一个人呆着,挺无聊的,还是学习最有趣,不论是什么,开阔视野都是好的. 参考网址:http://www.dowebok.com/77.html 上面有详细介绍及案例展示,很不错哦,可以先去看看 ...
- 关于linux服务器上搭建ftp服务的流程
小龙最近折腾了一个阿里云的服务器,买完了就要开始做那么多那么多的功课,小龙对ssh也是一知半解的状态,做个小笔记,发布下整个ftp服务的搭建过程,大神勿喷:) 一.aliyun Linux(Redha ...
- 我的Python学习之路 Python的初识与准备工作
注:文笔不好,不喜勿喷,当个段子看看就好 一.初识Python 第一次听到Python是在2016年大概暑假 时候(即将大三),因为对黑客技术的蜜汁热爱(虽然自己并不会),在玄魂大大的公众微信号中看到 ...
- 20145223《信息安全系统设计基础》 GDB调试汇编堆栈过程分析
20145223<信息安全系统设计基础> GDB调试汇编堆栈过程分析 分析的c语言源码 生成汇编代码--命令:gcc -g example.c -o example -m32 进入gdb调 ...
- dedecms 采集规则过滤与替换
过滤与替换常用操作:点击"常用规则",选择要过滤的代码段,再编辑成我们需要的.如果会文章简单采集了,接下来就需要过滤掉采集内容中的广告和链接及其它代码.一般的写法是{dede:tr ...
- iOS 利用Charles抓包
1.安装 Mac下好用的HTTP/HTTPS抓包工具Charles,到官网http://www.charlesproxy.com/可下载到最新版本(若不支持rMBP可拖到Retinizer中把文字变清 ...
- Maven+Spring Profile实现生产环境和开发环境的切换
第一步 Maven Profile配置 <profiles> <profile> <id>postgres</id> <activation> ...