ef数据库?entity framework 支持哪些数据库
大家好,关于ef数据库很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于entity framework 支持哪些数据库的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助!
entity framework 支持哪些数据库
EF可以支持多数据库的,比如sql server, mysql, oracle,它可以做到迁移数据库,可以几乎不改代码,但是,edmx其实是一个配置文件,也包含了目标数据库的信息。
如果要做到更改配置就可以切换数据库,那么,有以下几点:
1:3种数据库的provider的文档要仔细看,确认哪些功能是不被支持的,取支持功能的最小集,写进开发规范,规定哪些linq语句不允许写。
2:为3种数据库准备3套edmx,这样比较简单,也可以把ssld之类生成在dll之外,然后动态修改,但容易出错且麻烦。不论是dbfirset还是codefirst,根据目标数据库类型重新生成edmx都比较简单。
3:更改连接串,EF的连接串中,需要指定传统连接串/EF的provider/相应的edmx配置(ssld,csdl,msl),把这3个要素都根据1,2配置为你的目标数据库对应的配置之后,理论上,你的代码就可以直接运行。
EF code first 怎样创建数据库视图
1.使用CodeFirst方式创建数据库
我们新建一个控制台项目,项目中添加两个Model:Author和Blog以及DbContext。 DbContext的添加方式如下:
项目上右键->添加->新建项->ADO.NET Entity Data Model->Empty Code First model
项目代码如下:
1//默认生成的数据表名为类名+字母s,这里使用TableAttribute来指定数据表名为T_Authors
2 [Table("T_Authors")]
3 public class Author
4{
5 public int Id{ set; get;}
6 public string Name{ set; get;}
7/*
8此处定义了Blog类型的属性,所以要确保Blog类中至少要有一个表示主键的字段,即public int Id{ set; get;}。
否则在生成数据表时会报错:"EntityType'Blog' has no key defined. Define the key for this EntityType.
9 Blogs: EntityType: EntitySet'Blogs' is based on type'Blog' that has no keys defined."
10*/
11 public virtual ICollection<Blog> Blogs{ set; get;}
12}
13
14 [Table("T_Blogs")]
15 public class Blog
16{
17 public int Id{ set; get;}
18 public string Title{ set; get;}
19 public DateTime Time{ set; get;}
20 public int AuthorId{ set; get;}
21 public virtual Author Author{ set; get;}
22}
23
24 public class MyDbContext: DbContext
25{
26 public MyDbContext()
27: base("name=MyDbContext")
28{
29}
30//DbContext会根据配置文件中connectionStrings指定的数据库名称来建立数据库
31//DbContext根据DbSet属性的类型来创建数据表,这里指定了Author类型的属性,所以会生成T_Authors数据表
32 public virtual DbSet<Author> Authors{ set; get;}
33}
CodeFirst方式会根据配置文件中的配置生成数据库,这里小编使用的是MYSQL数据库,配置文件如下:
1<!--EF for MYSQL-->
2<entityFramework codeConfigurationType="MySql.Data.Entity.MySqlEFConfiguration, MySql.Data.Entity.EF6">
3<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework"/>
4<providers>
5<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6"/>
6</providers>
7</entityFramework>
8<connectionStrings>
9<add name="MyDbContext" connectionString="server=localhost;port=3306;database=EF;uid=root;password=root" providerName="System.Data.MySqlClient"/>
10</connectionStrings>
PS:小编使用的是EF6和MYSQL数据库,所以要在项目中添加对Mysql.Data.Entity.EF6以及EntityFrameword 6.0的引用。
到此,我们已经完成生成数据库的工作,接下来在Main方法中写两行代码:
1 using(var db= new ManagerDb())
2{
3 db.Authors.Add(new Author(){ Name="xfh"});
4 db.SaveChanges();
5}
efcore检测数据是不是创建
1.查询生命周期
在进入正题时候,我们先来了解EF Core查询的生命周期。
1.1LINQ查询会由Entity Framework Core处理并生成给数据库提供程序可处理的表示形式(说白了就是生成给数据库可识别数据形式)。
发送的查询结果(查询表示形式)会被缓存,以便每次执行查询时无需进行1.1中处理。
1.2查询结果(查询表示形式)会传递到数据库提供程序
数据库提供程序会识别出查询的哪些部分可以在数据库中求值。
查询的这些部分会转换为特定数据库的查询语言(例如,关系数据库的T-SQL)。
一个或多个查询会发送到数据库并返回结果集(返回的是数据库中的值,而不是实体实例中的)。
1.3对于结果集中的每一项
1.3.1如果这是跟踪查询(后续会讲到),EF会检查数据是否表示已在上下文实例的更改跟踪器中的实体中。
如果是,则会返回现有实体。
如果不是,则会创建新实体、设置更改跟踪并返回该新实体。
1.3.2如果这是非跟踪查询(后续会讲到),EF会检查数据是否表示已在此查询的结果集中的实体中。
如果是,则会返回现有实体。非跟踪查询使用弱引用跟踪已返回的实体。如果具有相同标识的上一个结果超出范围,并运行垃圾回收,则可能会获得新的实体实例。
如果不是,则会创建新实体并返回该新实体。
1.4执行查询时
当调用LINQ运算符时,只会生成查询的内存中表示形式。当我们使用查询结果(查询表示形式)时才会发送到数据库。导致查询发送到数据库的最常见操作如下:
在for循环中循环访问结果:
var blogs= from b in _context.Blog
select new
{
b.BlogId,
b.Url
};
//触发数据库查询
foreach(var blog in blogs)
{
var id= blog.BlogId;
}
当我们执行完LINQ运算符的时候,从SQL Server Profiler监控里面可以看到,并没有执行的SQL语句,也就是说查询结果blogs并没有立即发送给数据库获取返回数据结果集。
而当我们调试进去for循环时候,SQL Server Profiler监控里面可以看到出现了执行SQL语句。也就是说这时候查询结果blogs才执行发送给数据库返回结果集。
使用ToList、ToArray、Single、Count等运算符
_context.Blog.ToList();
_context.Blog.ToArray();
_context.Blog.Count();
_context.Blog.Single();
_context.Blog.First();
执行这种形式运算符也会立即发送到数据库获取结果集的。具体执行过程呈现,这里大伙自行测试吧。
将查询结果数据绑定到UI
2.跟踪查询与非跟踪查询
在1小节生命周期里面我们有提及过跟踪与非跟踪查询,现在我们来了解下这两种查询区别。
2.1跟踪查询
返回实体类型的查询是默认会被跟踪的,这表示如果这些实体实例有更改行为,会通过SaveChanges()持久化将更改的值更新到数据库中,但是如果更改的值跟实体实例的值相同,则不会持久化提交数据到数据库,这就是跟踪查询。在以下示例中,将检测到对博客链接所做的更改,并在 SaveChanges()期间将这些更改持久化到数据库中。
//返回blog实体类型的查询是默认会被跟踪
var blog= _context.Blog.SingleOrDefault(b=> b.BlogId== 1);
//检测对博客链接所做的更改
blog.Url="1";
//持久化保存到数据库中
_context.SaveChanges();
实体初始链接值是1,当我们点击Save按钮保存的时候,检测到对博客链接所做的更改值还是1的时候,并不会提交更改值到数据库中的。看看下图SQL Server Profiler监控就知道,并没有监控到对应有更新的T-SQL语句,也就是说并没有执行更新操作:
当我们再把链接值更改为2点击保存时候,EF Core检测到博客链接值已经从1更改为2,就会持久化保存到数据库中。
blog.Url="2";
废话少说,直接上图:
2.2非跟踪查询
如果不需要更新从数据库中检索到的实体,则应使用非跟踪查询。可以将单个查询替换为非跟踪查询。
var blogs= context.Blogs
//不用跟踪查询
.AsNoTracking()
.ToList();
//或者在上下文实例级别更改默认跟踪行为
context.ChangeTracker.QueryTrackingBehavior= QueryTrackingBehavior.NoTracking;
var blogs= context.Blogs.ToList();
还是一样老谭秘方事例,当你加上非跟踪查询标识后,无论怎么更改博客链接值,都不会持久化保存数据到数据库中的。
var blogs= _context.Blog
//不用跟踪查询
.AsNoTracking()
.SingleOrDefault(m=> m.BlogId== 1);
blogs.Url="2";
_context.SaveChanges();
直接上图跟踪结果:
在这相信大家从该小节跟踪与非跟踪查询中事例描述中总算对1小节查询生命周期有一定理解吧。
2.3跟踪和自定义投影
即使查询的结果类型不是实体类型,默认情况下EF Core也会跟踪结果中包含的实体类型。在以下返回匿名类型的查询中,结果集中的Blog实例会被跟踪。
var blog= context.Blogs
.Select(b=>
new
{
Blog= b,
PostCount= b.Posts.Count()
});
如果结果集包含来自LINQ组合的实体类型,EF Core将跟踪它们。
var blog= context.Blogs
.Select(b=>
new
{
Blog= b,
Post= b.Posts.OrderBy(p=> p.Rating).LastOrDefault()
});
如果结果集不包含任何实体类型,则不会执行跟踪。在以下查询中,我们返回匿名类型(具有实体中的某些值,但没有实际实体类型的实例)。查询中没有任何被跟踪的实体。
var blog= context.Blogs
.Select(b=>
new
{
Id= b.BlogId,
Url= b.Url
});
EF Core支持执行顶级投影中的客户端评估。如果EF Core具体化实体实例以进行客户端评估,则会跟踪该实体实例。此处,由于我们要将blog实体传递到客户端方法StandardizeURL,因此EF Core也会跟踪博客实例。
var blogs= context.Blogs
.OrderByDescending(blog=> blog.Rating)
.Select(blog=> new
{
Id= blog.BlogId,
Url= StandardizeUrl(blog)
})
.ToList();
public static string StandardizeUrl(Blog blog)
{
var url= blog.Url.ToLower();
if(!url.StartsWith("http://"))
{
url= string.Concat("http://", url);
}
return url;
}
到此这篇关于ASP.NET Core使用EF查询数据的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持。
点击收起内容
好了,关于ef数据库和entity framework 支持哪些数据库的问题到这里结束啦,希望可以解决您的问题哈!