2013-10-31 52 views
2

我们刚刚更新到EF6,并且遇到了与以前版本相比出现奇怪行为的问题。ef6 include()对于具有所需属性的可为null的属性

如果属性为空,则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查询?或者我可以强制包含在左边的JOIN?或者是我们唯一的选择回滚到以前的EF版本?

PS:我们使用的是.NET 4.0

感谢

+0

不要骗实体框架。如果您告诉它该属性是必需的,Entity Framework将相信它确实是必需的。为什么使用内置的'Required'属性具有您不喜欢的特定含义,而不是使用自定义属性? – hvd

+0

因为它运行得很好:)我以为MVC使用Required属性,但不是EF。如果必须将所有必需属性更改为与“必需”完全相同但未由EF拾取的自定义属性,那么这就是精神上的问题。一般而言,我相信如果以前的版本以某种方式表现出来,在刹车应用程序时改变这种行为并不是一个好主意。 – Intetics

+0

EF中EF也使用RequiredAttribute。但是,是的,我可以同意,如果在EF5中的使用方式不同,那么至少应该明确沟通变化。 – hvd

回答

0

我假设你想使用在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; } 
} 
+0

这是一个不错的选择。我相信它会起作用。然而,这是一个旧项目,有50个域模型,上帝知道有多少个视图(并且它们都使用域模型)。我们没有时间重构整个项目(即使我们理解它是正确的)。因此,如果我们没有找到强制它忽略此属性的方法,那么看起来我们将不得不回滚到EF的以前版本。 – Intetics

+0

@Intetics我明白,这将是一个相当重构的会议来改变它。但是如果你发现时间或者你要重建东西的时候,你一定要使用它们。 –

+0

同意。但与此同时,我们又回到了EF5(4.4),我将这个答案标记为正确的答案,尽管它不适合旧项目的黑暗现实。 – Intetics