- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
任务模式表明,为了保持一致,一切都必须完全异步或完全不异步。
通过首先使用实体框架设计器,我可以很容易地实现这一目标
var course = await db.Courses.FindAsync(CourseID);
Courses 是由 Entity Framework 生成的 DbSet,因此具有所有 Async 方法。问题是,如果我向该类添加导航属性,则后者不是 DbSet,并且它不包含任何异步方法定义。
例如,如果我将导航属性添加到 Students 表,它将被创建为虚拟 ICollection Students这意味着我不能使用异步方法。但我真正想要的是让 Entity Framework 自动生成一个 Task<>,以便能够等待导航属性。
这可能吗?我的目标是实现这样的目标:
var course = await db.Courses.FindAsync(CourseID);
var student = await course.Students.FindAsync(StudentID);
而目前我的选择是混合异步/非异步代码:
var course = await db.Courses.FindAsync(CourseID);
var student = course.Students.First(p => p.ID = StudentID);
或者根本不使用导航属性:
var course = await db.Courses.FindAsync(CourseID);
var student = await db.Students.Where(p => p.CourseID == course.ID && p.ID == StudentsID).FirstAsync();
您能否建议一个不需要代码优先的解决方案?
编辑根据 https://entityframework.codeplex.com/wikipage?title=Task-based%20Asynchronous%20Pattern%20support%20in%20EF.#AsyncLazyLoading我搜索的是所谓的“异步延迟加载”,目前还没有可用的功能(也许永远不会)。看来您可以使用延迟加载或异步功能,也许我应该通过等待 Task.Run(course.Students.First(p => p.ID = StudentID)) 将属性包装在任务中,但我不确定这是个好主意。
最佳答案
在我看来,延迟加载(在我看来是枚举导航属性会触发数据库访问的情况)是一种糟糕的访问模式,因为它只是意味着数据库访问将发生在意想不到的地方,这可以使应用程序性能难以预测。
以下所有解决方案都使用来自 System.Data.Entity
的导入.
解决方案 1:使用预先加载 Include
var course = await db.Courses.Include(c => c.Students).FirstOrDefaultAsync(c => c.ID == CourseID);
var student = course.Students.First(p => p.ID == StudentID);
优点:
Course
一次反对;Students
导航属性已加载,可以自由使用;缺点:
Student
即使您只需要一个对象,也会加载对象;解决方案 2:使用 LoadAsync
具体集合类上存在的方法;
此解决方案依赖于以下事实:延迟加载的集合来自 EntityCollection<TEntity>
类。
首先,我会定义一个扩展方法:
public static async Task LoadAsync<T>(ICollection<T> collection)
where T : class
{
if (collection == null) throw new ArgumentNullException("collection");
var entityCollection = collection as System.Data.Entity.Core.Objects.DataClasses.EntityCollection<T>;
if (entityCollection == null || entityCollection.IsLoaded) return;
await entityCollection.LoadAsync(CancellationToken.None).ConfigureAwait(false);
}
然后你可以这样写:
var course = await db.Courses.FindAsync(CourseID);
await course.Students.LoadAsync();
var student = course.Students.First(p => p.ID = StudentID);
优点:
Students
保证加载;缺点:
Course
和一组相关的Student
对象可能会变得陈旧,这可能会引发并发问题; (请注意,影响关系的并发问题比影响单个记录的并发问题更难解决)解决方案 3:使用 CreateSourceQuery
具体类上的方法仅加载 Student
你想要的对象。
好吧,这样做是行不通的,实际上是一个非常糟糕的主意。
然而,可以写出具有相同优点/缺点的解决方案,但采用另一种方式:
var course = await db.Courses.FindAsync(CourseID);
var studentsQuery = from c in db.Courses
where c.ID == CourseID
from s in c.Students
select s;
var student = await studentsQuery.FirstAsync(p => p.ID = StudentID);
优点:
Student
您将要使用的对象;缺点:
Students
导航属性未加载,这意味着它不能在不触发数据库访问的情况下使用;解决方案 4:预先加载,更具选择性:在初始 LINQ 查询中加载您感兴趣的类(class)和学生。
我不能 100% 确定该解决方案是否会按照所写的那样工作。
var query = from c in db.Courses
where c.ID == CourseID
select new { course = c, student = c.Students.First(p => p.ID == StudentID) };
var result = await query.FirstOrDefaultAsync();
var course = result.course;
var student = result.student;
优点:
缺点:
Students
导航属性未加载,这意味着它不能在不触发数据库访问的情况下使用;** 何时使用哪种解决方案? **
Course
时才使用解决方案 3。对象已加载;关于c# - Entity Framework Designer 首先获取导航属性作为任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25766025/
我需要您在以下方面提供帮助。近一个月来,我一直在阅读有关任务和异步的内容。 我想尝试在一个简单的 wep api 项目中实现我新获得的知识。我有以下方法,并且它们都按预期工作: public Htt
我的可执行 jar 中有一个模板文件 (.xls)。不需要在运行时我需要为这个文件创建 100 多个副本(稍后将唯一地附加)。用于获取 jar 文件中的资源 (template.xls)。我正在使用
我在查看网站的模型代码时对原型(prototype)有疑问。我知道这对 Javascript 中的继承很有用。 在这个例子中... define([], function () { "use
影响我性能的前三项操作是: 获取滚动条 获取偏移高度 Ext.getStyle 为了解释我的应用程序中发生了什么:我有一个网格,其中有一列在每个单元格中呈现网格。当我几乎对网格的内容做任何事情时,它运
我正在使用以下函数来获取 URL 参数。 function gup(name, url) { name = name.replace(/[\[]/, '\\\[').replace(/[\]]/,
我最近一直在使用 sysctl 来做很多事情,现在我使用 HW_MACHINE_ARCH 变量。我正在使用以下代码。请注意,当我尝试获取其他变量 HW_MACHINE 时,此代码可以完美运行。我还认为
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 关闭 9 年前。 要求提供代码的问题必须表现出对所解决问题的最低限度的理解。包括尝试过的解决方案、为什么
由于使用 main-bower-files 作为使用 Gulp 的编译任务的一部分,我无法使用 node_modules 中的 webpack 来require 模块code> dir 因为我会弄乱当
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 5 年前。 Improve this qu
我使用 Gridlayout 在一行中放置 4 个元素。首先,我有一个 JPanel,一切正常。对于行数变大并且我必须能够向下滚动的情况,我对其进行了一些更改。现在我的 JPanel 上添加了一个 J
由于以下原因,我想将 VolumeId 的值保存在变量中: #!/usr/bin/env python import boto3 import json import argparse import
我正在将 MSAL 版本 1.x 更新为 MSAL-browser 的 Angular 。所以我正在尝试从版本 1.x 迁移到 2.X.I 能够成功替换代码并且工作正常。但是我遇到了 acquireT
我知道有很多关于此的问题,例如 Getting daily averages with pandas和 How get monthly mean in pandas using groupby但我遇到
This is the query string that I am receiving in URL. Output url: /demo/analysis/test?startDate=Sat+
我正在尝试使用 javascript 中的以下代码访问 Geoserver 层 var gkvrtWmsSource =new ol.source.ImageWMS({ u
API 需要一个包含授权代码的 header 。这就是我到目前为止所拥有的: var fullUrl = 'https://api.ecobee.com/1/thermostat?json=\{"s
如何获取文件中的最后一个字符,如果是某个字符,则删除它而不将整个文件加载到内存中? 这就是我目前所拥有的。 using (var fileStream = new FileStream("file.t
我是这个社区的新手,想出了我的第一个问题。 我正在使用 JSP,我成功地创建了 JSP-Sites,它正在使用jsp:setParameter 和 jsp:getParameter 具有单个字符串。
在回答 StoreStore reordering happens when compiling C++ for x86 @Peter Cordes 写过 For Acquire/Release se
我有一个函数,我们将其命名为 X1,它返回变量 Y。该函数在操作 .on("focusout", X1) 中使用。如何获取变量Y?执行.on后X1的结果? 最佳答案 您可以更改 Y 的范围以使其位于函
我是一名优秀的程序员,十分优秀!