EntityFramework Core数据查询

前言

本节我们再来讲讲EF Core,本节算是回归基础吧,当前项目EF Core还是处于1.1版本中,后续等待.net core等版本稳定了全部会更新到2.0版本中,到时再来更新相关文章分享给大家。

相关数据加载

在EF中一直以来都是通过导航属性来加载一个实体的相关数据,在EF Core中加载相关数据有以下三种模式:

饥饿加载

来自数据库相关联数据的加载也会作为实体的一部分进行加载。

我们通过Include方法来进行饥饿加载实体相关联的数据,如下:

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
        .ToList();
}

当然我们也可以同时关联实体的多个属性,如下:

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
        .Include(blog => blog.Owner)
        .ToList();
}

同时我们也可以类似层级一样来加载一个实体的相关的实体的相关联实体,通过ThenInclude,如下:

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
            .ThenInclude(post => post.Author)
        .ToList();
}

是不是只要我们加上了Include方法就会加载一个实体相关联的数据呢,如下:

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
        .Select(blog => new
        {
            Id = blog.BlogId,
            Url = blog.Url
        })
        .ToList();
}

很明显我们最后只是投影了Blog中的几个字段,所以此时会忽略对Post导航属性的查询。当在这种情况下对于最后返回的数据未包含相关联数据时在日志文件中会进行提醒,在这种情况下我们很明确知道会忽略对导航数据的加载,同时也不会抛出异常,我们可以在日志文件中对该项处理进行忽略,如下:

 services.AddDbContext<EFCoreContext>(options =>
            {
                options.UseSqlServer(sqlStr, d => d.MigrationsAssembly("StudyEFCore"))
                .ConfigureWarnings(warnings => warnings.Throw(CoreEventId.IncludeIgnoredWarning);
            });

显式加载

来自数据库相关联数据的加载在稍后会进行加载。

显式加载只有在EF Core1.1版本上才会被支持,通过DbContext.Entry()来实现,如下:

using (var context = new BloggingContext())
{
    var blog = context.Blogs
        .Single(b => b.BlogId == 1);

    context.Entry(blog)
        .Collection(b => b.Posts)
        .Load();

    context.Entry(blog)
        .Reference(b => b.Owner)
        .Load();
}

当然我们也可以通过Linq来加载相关联数据,如下:

using (var context = new BloggingContext())
{
    var blog = context.Blogs
        .Single(b => b.BlogId == 1);

    var postCount = context.Entry(blog)
        .Collection(b => b.Posts)
        .Query()
        .Count();
}

延迟加载

来自数据库相关联数据的加载当导航属性被访问时会被加载,在EF Core中可能将会实现。

客户端数据评估进行翻译 

在EF Core中不像之前EF版本对于在lambda表达式中对数据进行操作此时将导致无法翻译从而出错,但是在EF Core中对于一些简单的数据可以进行了翻译,这一点还是让我们有了一点期待。我们一起来看看。

    public class Sample
    {
        public static string StandardizeUrl(string url)
        {
            url = url.ToLower();

            if (!url.StartsWith("http://"))
            {
                url = string.Concat("http://", url);
            }

            return url;
        }

        public static void Run()
        {
            using (var context = new BloggingContext())
            {
                var blogs = context.Blogs
                    .OrderByDescending(blog => blog.Rating)
                    .Select(blog => new
                    {
                        Id = blog.BlogId,
                        Url = StandardizeUrl(blog.Url)
                    })
                    .ToList();
            }

            using (var context = new BloggingContext())
            {
                var blogs = context.Blogs
                    .Where(blog => StandardizeUrl(blog.Url).Contains("dotnet"))
                    .ToList();
            }
        }
    }

同时这种对于代码进行评估进行翻译的情况我们也可以进行禁用,如下:

            services.AddDbContext<EFCoreContext>(options =>
            {
                options.UseSqlServer(sqlStr, d => d.MigrationsAssembly("StudyEFCore"))
                .ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning));
            });

总结

本文简单讲解了下EF Core中相关数据加载的三种模式以及对于客户端数据能够进行简单的翻译,我们下节再见。

时间: 2024-09-20 11:01:52

EntityFramework Core数据查询的相关文章

EntityFramework 7 更名为EntityFramework Core(预发布状态)

前言 最近很少去学习和探索新的东西,尤其是之前一直比较关注的EF领域,本身不太懒,但是苦于环境比较影响自身的心情,所以迟迟没有下笔,但是不去学习感觉在精神层面缺少点什么,同时也有园友说EF又更新了,要我再写一篇,最终经过思想斗争后,还是花了一点时间去继续探索.本篇比较理论的去分享最近EF进展,后面有时间会继续关注EF团队在EF上的动向,并给出相对应的实例. EF Core 1.0.0 (1)EntityFramework是微软在.NET中推荐使用的数据访问技术,而EntityFramework

EntityFramework Core 1.1有哪些新特性呢?我们需要知道

前言 在项目中用到EntityFramework Core都是现学现用,及时发现问题及时测试,私下利用休闲时间也会去学习其他未曾遇到过或者用过的特性,本节我们来讲讲在EntityFramework Core 1.1中出现了哪些新特性供我们使用. EntityFramework Core 1.1新特性探讨 DbSet.Find 在EF 6.x中也有此方法的实现,在EF Core 1.1中也同样对此方法进行了实现,为什么要拿出来讲呢,当然也有其道理,我们一起来看看.在仓储中我们实现Find这个方法,

EntityFramework Core并发深挖详解,一纸长文,你准备好看完了吗?

前言 之前有关EF并发探讨过几次,但是呢,博主感觉还是有问题,为什么会觉得有问题,其实就是理解不够透彻罢了,于是在项目中都是用的存储过程或者SQL语句来实现,利用放假时间好好补补EF Core并发的问题,本文比较长,请耐心点看. EntityFramework Core并发初级版初探 关于并发无非就两种:乐观并发和悲观并发,悲观并发简言之则是当客户端对数据库中同一值进行修改时会造成阻塞,而乐观并发则任何客户端都可以对可以对数据进行查询或者读取,在EF Core中不支持悲观并发,结果则产生并发冲突

EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解

前言 我比较喜欢安静,大概和我喜欢研究和琢磨技术原因相关吧,刚好到了元旦节,这几天可以好好学习下EF Core,同时在项目当中用到EF Core,借此机会给予比较深入的理解,这里我们只讲解和EF 6.x中不同,相同的则不再叙述. EntityFramework Core 1.1方法理论详解 当我们利用EF Core查询数据库时如果我们不显式关闭变更追踪的话,此时实体是被追踪的,关于变更追踪我们下节再叙.就像我们之前在EF 6.x中讨论的那样,不建议手动关闭变更追踪,对于有些特殊情况下,关闭变更追

EntityFramework Core不得不注意的性能优化意外收获,你会用错?

前言 这两天在着实研究EF Core项目当中对于一些查询也没实际去检测,于是想着利用放假时间去实际测试下,结果本文就出来了,too young,too simple,后续博主会从底层翻译表达式树弄起,来从源头了解EF Core,通过本文你会明白不是EF Core团队没做性能优化,而是你根本就没用过而且正在倒退. EntityFramework Core性能优化初探 简单粗暴直接上代码,给出上下文以及需要用到的测试类,如下: public class EFCoreContext : DbConte

EntityFramework Core饥饿加载忽略导航属性问题

前言 .NET Core项目利用EntityFramework Core作为数据访问层一直在进行中,一直没有过多的去关注背后生成的SQL语句,然后老大捞出日志文件一看,恩,有问题了,所以本文产生了,也是有点疑惑,若有知情者,还望告知. EntityFramework Core忽略导航属性  在前面我们已经探讨过利用Serilog日志框架来输出日志,所以对于本节查询日志的输出依然借助Seilog.我们在Startup.cs类中Starup方法中是创建日志实例. Log.Logger = new L

EntityFramework Core Raw SQL

前言 本节我们来讲讲EF Core中的原始查询,目前在项目中对于简单的查询直接通过EF就可以解决,但是涉及到多表查询时为了一步到位就采用了原始查询的方式进行.下面我们一起来看看. EntityFramework Core Raw SQL 基础查询(执行SQL和存储过程) 啥也不说了,拿起键盘就是干,如下: public class HomeController : Controller { private IBlogRepository _blogRepository; public HomeC

EntityFramework Core问题处理集锦(一)

前言 和大家脱离了一段时间,有时候总想着时间挤挤总是会有的,但是并非人愿,后面会借助周末的时间来打理博客,如有问题可以在周末私信我或者加我QQ皆可,欢迎和大家一起探讨,本节我们来讨论EF Core中的一些问题后面陆陆续续会将EF Core中需要注意的地方补充上来,有些是我一直以来比较疏忽的地方,不喜勿喷.用在实际项目中的时候才发现和平时所学有很大差异,靠着项目才能检验出真理. EntityFramework Core问题集锦 更新单个实体 更新单个实体的方式有两种: (1)查询出实体进行赋值更新

运用 ADO.NET 对象优化数据查询代码

ado|对象|数据|优化    毫无疑问,ADO.NET 向人们提供了一种功能强大.仿真数据库的对象模型,它可以将数据记录保存到内存中.尤其是ADO.net 的 DataSet 类,它不但在功能上相当于数据库表的集中存储器(central repository),而且支持表间的各种约束和逻辑关系.进一步说来,DataSet 对象其实是一种离线数据容器.     乍一看,只要把 DataSet 类的所有特性联合起来,就能消除 SQL 查询命令中的复杂子句,比如那些泛滥成灾且层层嵌套的 INNER