EF codefirst:我应该初始化导航属性吗?

2023-12-13

我看过一些书(例如编程实体框架代码优先 Julia Lerman)定义其域类(POCO),无需初始化导航属性,例如:

public class User
{
    public int Id { get; set; }
    public string UserName { get; set; }

    public virtual ICollection<Address> Address { get; set; }
    public virtual License License { get; set; }
}

一些其他书籍或工具(例如实体框架电动工具)生成 POCO 时会初始化该类的导航属性,例如:

public class User
{
    public User()
    {
        this.Addresses = new IList<Address>();
        this.License = new License();
    }
    public int Id { get; set; }
    public string UserName { get; set; }

    public virtual ICollection<Address> Addresses { get; set; }
    public virtual License License { get; set; }
}

Q1:哪个更好?为什么?优点和缺点?

Edit:

public class License
{
    public License()
    {
        this.User = new User();
    }
    public int Id { get; set; }
    public string Key { get; set; }
    public DateTime Expirtion { get; set; }

    public virtual User User { get; set; }
}

Q2:在第二种方法中,如果“License”类也引用了“User”类,则会出现堆栈溢出。这意味着我们应该有单向引用。(?)我们应该如何决定应该删除哪一个导航属性?


收藏:没关系。

作为导航属性,集合和引用之间存在明显的区别。参考is一个实体。一个集合contains实体。这意味着初始化集合是无意义的就业务逻辑而言:它没有定义实体之间的关联。设置参考即可。

因此,是否或如何初始化嵌入列表纯粹是一个偏好问题。

至于“如何”,有些人更喜欢延迟初始化:

private ICollection<Address> _addresses;

public virtual ICollection<Address> Addresses
{ 
    get { return this._addresses ?? (this._addresses = new HashSet<Address>());
}

它可以防止空引用异常,因此有利于单元测试和操作集合,但它也可以防止不必要的初始化。当一个类具有相对较多的集合时,后者可能会产生影响。缺点是它需要相对较多的管道,尤其是。与没有初始化的自动属性相比。此外,C# 中空传播运算符的出现使得初始化集合属性不再那么紧迫。

...除非应用显式加载

唯一的问题是初始化集合使得很难检查实体框架是否加载了集合。如果初始化了一个集合,则像这样的语句...

var users = context.Users.ToList();

...将创建User具有空、非空的对象Addresses集合(除了延迟加载)。检查集合是否已加载需要类似的代码...

var user = users.First();
var isLoaded = context.Entry(user).Collection(c => c.Addresses).IsLoaded;

如果集合没有初始化一个简单的null检查就可以了。因此,当选择性显式加载是编码实践的重要组成部分时,即......

if (/*check collection isn't loaded*/)
    context.Entry(user).Collection(c => c.Addresses).Load();

...不初始化集合属性可能更方便。

参考属性: 不

引用属性是实体,因此为它们分配一个空对象是有意义的.

更糟糕的是,如果您在构造函数中启动它们,EF 在具体化对象或通过延迟加载时不会覆盖它们。它们将始终具有其初始值,直到您actively替换它们。更糟糕的是,您甚至可能最终在数据库中保存空实体!

还有另一个效果:关系修复不会发生。关系修复是 EF 通过导航属性连接上下文中所有实体的过程。当一个User and a Licence分别加载,仍然User.License将被填充,反之亦然。当然,除非如果License已在构造函数中初始化。对于 1:n 关联也是如此。如果Address会初始化一个User在其构造函数中,User.Addresses不会有人居住!

实体框架核心

实体框架核心(撰写本文时为 2.1)中的关系修复不受构造函数中初始化的引用导航属性的影响。也就是说,当分别从数据库中提取用户和地址时,将填充导航属性。
然而,延迟加载确实not覆盖初始化的参考导航属性。

在 EF-core 3 中,初始化引用导航属性会阻止Include无法正常工作。

因此,总而言之,同样在 EF-core 中,在构造函数中初始化引用导航属性可能会导致问题。不要这样做。无论如何,这没有意义。

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

EF codefirst:我应该初始化导航属性吗? 的相关文章

随机推荐

  • 迭代 PriorityQueue 不会产生有序结果

    import java util class Priority public static void main String args PriorityQueue
  • python正则表达式中的匹配括号[重复]

    这个问题在这里已经有答案了 我有类似的东西 store s 结束行就像 1 家商店 我想使用Python正则表达式来匹配它 我尝试过类似的东西re match store s text 但它不起作用 这是我尝试过的代码 import re
  • Jenkins - 构建步骤之间的条件

    我想使用 Jenkins 构建一个 Maven 项目 但是 只有当 SVN 存储库中的某个文件发生更改 并且包含特殊密钥 时才必须构建项目 所以我的计划是创建一个包含两个构建步骤的作业 第一步执行一个 shell 或 python 脚本来检
  • Delphi非可视化TTree实现

    我正在寻找一种非可视持久树 TStringTree 实现 如果有人知道它的任何良好实施 请告诉我 Thanks 你会发现一个灵活的 非可视化的树结构DI 容器图书馆 商业 然而 正如其他人上面所指出的 开发自己的功能确实非常容易 只需添加您
  • /proc 的内核模块

    如何编写一个内核模块 在 proc 中创建一个名为 mymod 的目录 并在其中创建一个名为 mymodfile 的文件 该文件在写入时应接受 1 到 3 范围内的数字 并在读取时根据已写入的数字返回以下消息 1 当前系统时间 以微秒精度为
  • RenderScript 源代码在哪里

    我正在大学项目中研究 RenderScript 我们想要找到选择 RenderScript 代码运行位置的调度程序 在 CPU 上 GPU DSP 并研究它如何做出这种选择 问题是 我们找不到与调度程序相关的任何源代码 事实上 我们在源代码
  • 在 Swift 中修改字典数组

    我是 Swift 新手 在理解数组和字典的某些方面遇到了一些麻烦 我有一个字典数组 我使用了类型别名 例如 typealias myDicts Dictionary
  • 无服务器框架 v1 - 一个服务中的多个资源

    我有两个资源 游戏和玩家 都有crud功能 这些应该位于同一个无服务器服务中吗 我想将它们分开 但是如何将它们放在同一个 api 网关中 无服务器框架项目部署单个 API 网关 因此 如果您希望它位于不同的 API 网关中 您需要单独的无服
  • 获取 Internet Explorer 选项卡标题

    我正在尝试获取所有打开的 IE 选项卡标题的列表或搜索特定的选项卡标题 我一直在使用它 但由于某种原因并不适用于每个选项卡 Get a handle to an application window DllImport USER32 DLL
  • 删除数组中的重复项

    我编写了一个程序来删除数组中的重复项 但该程序的 if 条件始终保持为 true 我明白问题所在 将 arr i 更改为 arr count 并通过 malloc 分配内存 但程序按原样打印数组而不删除重复项 include
  • MFC 对话框资源可以附加到 CChildView 吗?

    我有一个单文档 MFC 应用程序 其中包含MainFrame 源自 CFrameWnd 并包含在其中CChildView 派生形式CWnd 这些是由 VS MFC 向导生成的 在资源编辑器中 我设计了一个简单的 UI 并将其标记为IDD C
  • jQuery 点击事件返回 false

    我的点击事件设置如下 dialogLink click function dialog this return false 都有一个 return false 有人可以解释一下它的作用以及是否需要吗 你什么时候回来false从事件处理程序中
  • 403 Forbidden(错误代码:50001):添加角色时缺少访问权限 |不和谐.py

    我正在尝试快速为人们分配不同的角色 以便给用户留下他们的名字是 Rainbow 的印象 是的 我知道这违反了 TOS 并且我首先在删除角色之前为人们添加角色 但是 在添加角色时 我在这篇文章的标题中收到错误 我已经研究过这个问题并尝试了很多
  • 在 NumPy 数组的每个单元格高效评估函数

    给定 NumPy 数组A 最快 最有效的应用方法是什么same功能f to every cell 我分配给A i j by f A i j 功能f 没有二进制输出 因此屏蔽操作无济于事 每个单元格的双循环迭代是最佳解决方案吗 你可以只是矢量
  • Android凌空上传图片

    我跟着本教程将图像上传到我的服务器 但是 一旦我单击图库中的一张图片 它就会关闭我的应用程序 我有两个按钮 一个用于浏览 另一个用于用户做出选择后上传 要浏览我这样做 private void showFileChooser Intent
  • 对 URL 字符串中的 ID 进行加密/编码

    只是想在我的网站上做一些安全工作 并尝试找出确保 ID 安全的最佳途径 例子 http localhost page php id 90 TO http localhost share 22349234987sdsdf9sdf8742349
  • PDF 文件的 CUPS 打印

    我怎样才能告诉lpr命令 CUPS 我的文件实际上是 PDF lpr file pdf 不会打印任何东西 这真的是基于 CUPS 的吗 lpr 还是安装 CUPS 之前未删除的另一个假脱机系统的残余 通过运行来检查ldd which lpr
  • Microsoft graph API:通过 iCalUid 查找事件

    我想拒绝一次定期会议 我只有 masterSerieId iCalId 该实例的时间 你知道我如何取消该实例吗 我是否必须使用实例的 masterId 和时间进行查询才能查找事件 id 还是有一种方法可以使用 iCalId 查找 event
  • Python 线程并没有提高速度

    为了加速某个列表处理逻辑 我编写了一个装饰器 它会 1 拦截传入的函数调用 2 获取其输入列表 将其分成多个部分 4 将这些部分传递给单独线程上的原始函数 5 组合输出和返回 我认为这是一个非常巧妙的想法 直到我对其进行编码并发现速度没有变
  • EF codefirst:我应该初始化导航属性吗?

    我看过一些书 例如编程实体框架代码优先 Julia Lerman 定义其域类 POCO 无需初始化导航属性 例如 public class User public int Id get set public string UserName