为什么即使我在每个可能的点将其关闭后,我的代码仍会执行延迟加载?

2024-04-14

我想要获取具有 UserTest 实体的考试和测试实体,该实体的 UserId 等于“0”或等于提供的值。我提出了很多建议,但到目前为止都没有奏效。一个建议是从获取 UserTest 数据开始,另一种解决方案是从获取 Exam 数据开始。这是我使用 UserTests 作为源起点时得到的结果。

我有以下 LINQ:

        var userTests = _uow.UserTests
            .GetAll()
            .Include(t => t.Test)
            .Include(t => t.Test.Exam)
            .Where(t => t.UserId == "0" || t.UserId == userId)
            .ToList();

当我检查时_uow.UserTests使用调试器它是一个存储库,当我检查dbcontext's configuration.lazyloading然后它被设置为false.

这是我的课程:

public class Exam
{
    public int ExamId { get; set; }
    public int SubjectId { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Test> Tests { get; set; }
}

public class Test
{
    public int TestId { get; set; }
    public int ExamId { get; set; }
    public string Title { get; set; }
    public virtual ICollection<UserTest> UserTests { get; set; }
}

public class UserTest
{
    public int UserTestId { get; set; }
    public string UserId { get; set; }
    public int TestId { get; set; }
    public int QuestionsCount { get; set; }
}

当我查看输出时,我看到了这样的内容:

[{"userTestId":2,
  "userId":"0",
  "testId":12,
  "test":{
      "testId":12,"examId":1,
      "exam":{
          "examId":1,"subjectId":1,
          "tests":[
               {"testId":13,"examId":1,"title":"Sample Test1",
                "userTests":[
                      {"userTestId":3,
                       "userId":"0",

请注意,它会得到一个UserTest对象,然后获取测试对象,然后获取检查对象。然而,考试对象包含一个测试集合,然后它再次返回并获取其中的不同测试和单元测试:

UserTest > Test > Exam > Test > UserTest ?

我已尽力确保关闭延迟加载并调试告诉我它设置为false。我在用EF6 and WebAPI但不确定这是否有什么不同,因为我正在调试C# level.


无论您是通过急切加载还是延迟加载来加载相关实体,都无法避免由 EF 填充反向导航属性。这种关系修复(正如@Colin 已经解释的那样)是一个你无法关闭的功能。

您可以通过在查询完成后取消不需要的反向导航属性来解决该问题:

foreach (var userTest in userTests)
{
    if (userTest.Test != null)
    {
        userTest.Test.UserTests = null;
        if (userTest.Test.Exam != null)
        {
            userTest.Test.Exam.Tests = null;
        }
    }
}

然而,在我看来,你的设计的缺陷是你试图序列化entities代替数据传输对象(“DTO”)专门用于要将数据发送到的视图。通过使用 DTO,您可以避免完全不需要的反向导航属性,以及视图中不需要的其他实体属性。您可以定义三个 DTO 类,例如:

public class ExamDTO
{
    public int ExamId { get; set; }
    public int SubjectId { get; set; }
    public string Name { get; set; }
    // no Tests collection here
}

public class TestDTO
{
    public int TestId { get; set; }
    public string Title { get; set; }
    // no UserTests collection here

    public ExamDTO Exam { get; set; }
}

public class UserTestDTO
{
    public int UserTestId { get; set; }
    public string UserId { get; set; }
    public int QuestionsCount { get; set; }

    public TestDTO Test { get; set; }
}

然后使用投影来加载数据:

var userTests = _uow.UserTests
    .GetAll()
    .Where(ut => ut.UserId == "0" || ut.UserId == userId)
    .Select(ut => new UserTestDTO
    {
        UserTestId = ut.UserTestId,
        UserId = ut.UserId,
        QuestionsCount = ut.QuestionsCount,
        Test = new TestDTO
        {
            TestId = ut.Test.TestId,
            Title = ut.Test.Title,
            Exam = new ExamDTO
            {
                ExamId = ut.Test.Exam.ExamId,
                SubjectId = ut.Test.Exam.SubjectId,
                Name = ut.Test.Exam.Name
            }
        }
    })
    .ToList();

您还可以通过仅定义一个包含视图所需的所有属性的 DTO 类来“展平”对象图:

public class UserTestDTO
{
    public int UserTestId { get; set; }
    public string UserId { get; set; }
    public int QuestionsCount { get; set; }

    public int TestId { get; set; }
    public string TestTitle { get; set; }

    public int ExamId { get; set; }
    public int ExamSubjectId { get; set; }
    public string ExamName { get; set; }
}

投影将变得更简单,如下所示:

var userTests = _uow.UserTests
    .GetAll()
    .Where(ut => ut.UserId == "0" || ut.UserId == userId)
    .Select(ut => new UserTestDTO
    {
        UserTestId = ut.UserTestId,
        UserId = ut.UserId,
        QuestionsCount = ut.QuestionsCount,
        TestId = ut.Test.TestId,
        TestTitle = ut.Test.Title,
        ExamId = ut.Test.Exam.ExamId,
        ExamSubjectId = ut.Test.Exam.SubjectId,
        ExamName = ut.Test.Exam.Name
    })
    .ToList();

通过使用 DTO,您不仅可以避免反向导航属性的问题,还可以遵循良好的安全实践,将数据库中公开的属性值显式“列入白名单”。假设您要添加一个测试访问权限Password财产给Test实体。使用序列化急切加载的具有所有属性的完整实体的代码,密码也会被序列化并通过网络运行。您无需更改任何代码即可发生这种情况,并且在最坏的情况下,您不会意识到您在 HTTP 请求中暴露了密码。另一方面,当您定义 DTO 时,如果您将此属性显式添加到 DTO 类,则新的实体属性只会使用您的 Json 数据进行序列化。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么即使我在每个可能的点将其关闭后,我的代码仍会执行延迟加载? 的相关文章

随机推荐

  • 在 Java 中如何检查字节数组是否包含 Unicode 字符串?

    给定一个 UTF 8 编码字符串或任意二进制数据的字节数组 可以使用哪些方法in Java来确定它是哪一个 该数组可以由类似于以下的代码生成 byte utf8 Hello World getBytes UTF 8 或者 它可能是由类似于以
  • Ansible:全局模板文件夹?

    谷歌搜索找不到任何东西 有group vars 全部 对于变量 有类似的模板吗 我想在多个角色中使用一些模板 您可以将全局模板放入templatesAnsible 布局顶层目录 与group vars 顺便说一句 全局文件也是如此 file
  • 数组指针的常量正确性?

    有人争论说 在现代 C 语言中 我们应该始终通过数组指针将数组传递给函数 因为数组指针具有强类型 例子 void func size t n int arr n int array 3 func 3 array 这听起来可能是防止各种类型相
  • dask 可以用于在核心之外进行分组和重新编码吗?

    我有 8GB csv 文件和 8GB RAM 每个文件每行有两个字符串 格式如下 a c c a f g a c c a b f c a 对于较小的文件 我删除重复项 计算前两列中每行的副本数 然后将字符串重新编码为整数如下 https s
  • 使用 VBA 选择“查找”的第二个结果

    我正在努力做到这一点 以便我可以找到 lights 的第二个结果 以防该术语出现各种情况 下面的代码查找所考虑范围内的第一个匹配项 Dim ws As Worksheet Dim rng1 As Range Dim y As Range C
  • 如何使用javascript根据用户需求触发媒体查询

    我有一个响应式网页 针对不同的屏幕尺寸具有不同的设计 我正在使用 mediaquery 来更改我的设计 我想让用户能够更改更小或更大屏幕尺寸的设计 即使屏幕尺寸没有改变 是否可以在不改变屏幕尺寸的情况下用js触发 mediaquery 看一
  • Maven archetype + Velocity:如何显示日期

    我有一个 Maven 原型项目 当我使用这个原型时 我希望一些文件报告实际日期 我尝试使用 date 但 Velocity 无法识别它 我发现了一个叫做 DateTools 的东西 但我不知道如何使用它 这是我第一次使用 Velocity
  • pip 在 Docker 中被杀死

    我正在构建一个基于 Docker 容器python 3 7 slim stretch 同样的问题也发生在python 3 7 slim stretch 并且它正在变得Killed on pip install no cache dir ve
  • PhoneGap css 媒体查询方面不起作用

    我开发了一个以 iPhone 作为设计目标 即 640x960 gt 2 3 的应用程序 并且我使用布局中每个分区的百分比来实现此目的 以便 ui 相对于设备尺寸进行扩展 现在 这在 iPad 上运行良好 但我在使用 9 16 宽高比设备时
  • ImportError: libf77blas.so.3: 无法打开共享对象文件: 没有这样的文件或目录 Raspberry Pi3

    我有一个 Raspberry Pi3 我的目标是作为专用服务器运行几个 python3 脚本 到目前为止 我已经使用 pip3 安装了以下软件包 numpy 熊猫 scipy python Levenshtein fuzzywuzzy 还有
  • 将 Angular 从 12 升级到 13 添加了不能在模块外部使用 import.meta

    我将 Angular 项目从 12 升级到 13 但出现错误 未捕获的语法错误 无法在模块外部使用 import meta 我想在我的项目中同时使用 require 和 import 我尝试使用 type module 但在 webpack
  • 为什么从数组转换为图像时会出现位移?

    我正在尝试从 numpy 数组创建 QPixmap numpy 数组图像将是二维的 即没有颜色信息 只有灰度 我正在尝试适应这一点answer https stackoverflow com a 9796921 1764089满足我的需要
  • Android 图像裁剪 Uri 异常

    首先 我使用的是 Xamarin 但问题在本机 Java 项目上是相同的 我正在将 SDK 更新到 5 1 并在之前运行良好的代码上遇到了一个奇怪的错误 imageStream file imageStream Mvx Trace path
  • 启动 minikube 时无法设置 kubeconfig

    我已经安装了kubectl and minikube在我的 Windows 环境中 但是运行时minikube 启动它在 virtualBox 上创建虚拟机 但当它尝试在 Docker 上准备 kubernetes 时出现此错误 C Use
  • 对 Int32 或 UInt32 中的位进行哈希处理的好方法是什么?

    我有一个伪随机数生成器的实现 特别是 George Marsaglia 的 XOR Shift RNG 我的实现在这里 FastRandom cs http sharpneat svn sourceforge net svnroot sha
  • Auth0 不会在页面刷新时保留电子邮件/密码的登录信息

    我使用 Auth0 作为使用 React 的 SPA 的身份验证提供程序 我已遵循Auth0 反应教程 https auth0 com docs quickstart spa react 01 login and 这个更详细的教程 http
  • 如何以编程方式评估托管 bean 中的 EL

    我想在基于 Seam JSF 的应用程序中添加一个简单的模板语言 让用户撰写自己的电子邮件 由于我不想创建新的解析器 因此我想使用统一表达语言自行设置上下文 我怎样才能做到这一点 如果您位于 JSF 上下文中 那么只需使用Applicati
  • 如何动态有效地应用 RTL

    每当我应用时 我都会在线性布局中动态创建和添加 TextViewlayoutAmount setRotationY 180 布局改变了方向 这是正确的 但是里面的 TextViews 的单词也改变了方向 这是错误的 例如 如果这个单词很抱歉
  • 用于代码分割的 Webpack 配置不适用于生产构建

    使用 Webpack 构建 ReactJS 应用程序 最近对使用代码分割来减少应用程序大小感兴趣 我尝试实现一个包装 System import 的自定义 HOC async index tsx at a very high level l
  • 为什么即使我在每个可能的点将其关闭后,我的代码仍会执行延迟加载?

    我想要获取具有 UserTest 实体的考试和测试实体 该实体的 UserId 等于 0 或等于提供的值 我提出了很多建议 但到目前为止都没有奏效 一个建议是从获取 UserTest 数据开始 另一种解决方案是从获取 Exam 数据开始 这