【问题标题】:ef6 include() for nullable properties with required attributeef6 include() 用于具有必需属性的可空属性
【发布时间】:2013-10-31 15:49:48
【问题描述】:

我们刚刚更新到 EF6,与之前的版本相比,遇到了一个奇怪的行为问题。

如果属性可以为空,则 EF 用于为 Include 语句生成 LEFT JOIN。然而,看起来这个版本也考虑了 [required] 属性。

例如我有以下课程:

public class Client
{    
    [DisplayName("Industry Code")]
    [Required]
    public int? IndustryId { get; set; }

    [ForeignKey("IndustryId")]
    public Industry IndustryEntity { get; set; }
}

当我们这样做时

return db.Clients
    .Include(o => o.CountryISOEntity)
        .... 
    .Include(o => o.IndustryEntity)
    .Single(o => o.Id == clientId);

之前的版本生成了LEFT OUTER JOIN,新版本生成了INNER JOIN。

如果我删除 [required] 属性,它会生成 LEFT JOIN。但在我的情况下,这不是一个选项,因为我们使用此属性向用户显示错误,但是用户可以选择保存不完整的实体并稍后返回它。当用户回来时,它会收到一个错误,即记录不存在,因为包含生成 INNER JOIN。

新的 EF6 中是否有设置来禁用此行为(忽略属性)并根据可为空的信息生成 sql 查询?或者我可以强制包含中的 LEFT JOIN 吗?还是我们唯一的选择是回滚到以前的 EF 版本?

PS:我们使用的是 .Net 4.0

谢谢

【问题讨论】:

  • 不要对实体框架撒谎。如果您告诉它该属性是必需的,Entity Framework 将相信它确实是必需的。为什么要使用内置的 Required 属性,而不是使用自定义属性?
  • 因为它之前运行良好 :) 我认为 MVC 使用了 Required 属性,而不是 EF。如果我必须将所有必需属性更改为与必需属性完全相同但未被 EF 拾取的自定义属性,那是很明智的。总的来说,我相信如果以前的版本以一种方式表现,那么改变这种行为并不是一个好主意,因为它会阻碍应用程序。
  • RequiredAttribute 也被 EF 在 EF5 中使用。但是,是的,我同意如果它在 EF5 中以不同的方式使用,那么至少应该清楚地传达更改。

标签: c# .net asp.net-mvc-3 entity-framework


【解决方案1】:

我假设您想在 MVC 中使用 Required 属性进行表单验证,而不是告诉实体框架该属性是必需的。这就是您需要视图模型的原因,因此您可以将视图的验证逻辑与实体框架验证逻辑分开。

您的视图模型代表一个视图并包含呈现该视图所需的所有数据。域模型(实体)代表数据库中的一个(或多个)表。视图模型不一定包含与域模型相同的属性。以我个人的经验,它们通常是不同领域模型的组合。

如果您为Client 创建视图模型,则可以从您的 EF POCO 中删除验证属性。

视图模型将如下所示:

public class ClientModel
{
    [DisplayName("Industry Code")]
    [Required]
    public int IndustryId { get; set; }

    // Other properties..
}

那么你的 POCO 可以如下所示:

public class Client
{
    public int? IndustryId { get; set; }

    [ForeignKey("IndustryId")]
    public Industry IndustryEntity { get; set; }
}

【讨论】:

  • 这是一个不错的选择。我相信它会奏效。然而,这是一个旧项目,那里有大约 50 个领域模型,天知道有多少视图(而且它们都使用领域模型)。我们将没有时间重构整个项目(即使我们理解这是正确的方式)。所以看起来如果我们找不到强制它忽略这个属性的方法,我们将不得不回滚到以前版本的 EF。
  • @Intetics 我了解,更改它将是一个相当大的重构会话。但如果你有时间或打算重建东西,你绝对应该使用它们。
  • 同意。但与此同时,我们正在回滚到 EF5 (4.4),我将这个答案标记为正确的答案,即使它不适合旧项目的黑暗现实。
  • @Intetics 好的,谢谢。祝您发展顺利!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-14
  • 2013-12-27
  • 2019-11-30
  • 2017-07-29
  • 1970-01-01
  • 2013-01-07
  • 1970-01-01
相关资源
最近更新 更多