EF Include始终为第一个导航属性生成INNER JOIN

Ale*_* K. 4 .net c# linq asp.net entity-framework

我正在使用Code First方法并具有以下模型:

public class Person
{
    public int ID {get; set;}
    public string Name {get; set;}

    public int CurrentStationID {get; set;}
    public virtual Station CurrentStation {get; set;}

    public int CurrentTransportationID {get; set;}
    public virtual Transportation CurrentTransporation {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

以下代码在我的控制器中:

Models.Person model = myDBContext.Persons
                        .Include("CurrentStation")
                        .Include("CurrentTransportation")
                        .Where(p => p.ID == 1)
                        .FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

即使在DB表"人员"中存在具有(1,"Testname",0,0)的行,"model"也将为NULL .

以上生成一个SQL语句[...] INNER JOIN stations AS [...] LEFT JOIN transportations [...].对于我的所有模型,它始终为第一个导航属性执行INNER JOIN,无论基础表/类型是什么或我指定它们的顺序,它始终是第一个Include().

希望INNER JOIN而是所有的LEFT JOIN,因为"CurrentStation"不需要在数据库中.

为什么EF会这样做?我不明白,但我想明白.我没有在任何属性上指定[Required] - 属性,但它的行为就像我做的那样.

不幸的是,没有[Optional] -attribute并且通过OnModelCreate-override执行"HasOptional()"对我来说不是一个选项.

mre*_*ros 7

如果我没有弄错,为了允许属性是可选的或在数据库意义上,可以为空,你必须使属性可以为空.因此,对于CurrentStationId属性,您可以尝试按如下方式声明:

 public int? CurrentStationId {get;set;}
Run Code Online (Sandbox Code Playgroud)

更新帖子可能对您的情况有所帮助.

  • @AlexK.:你显然没有*强制执行*DB中的外键关系(FK是'0`(不是'NULL`!)但是没有PK =`0`的相关行),就像这里: http://stackoverflow.com/questions/7639417/entity-framework-and-forced-inner-join.如果您无法更改此情况,则可以停止使用Entity Framework映射数据库.如果模型中的关系是*required*,EF将创建一个INNER JOIN(并且只要您的PK属性不可为空,它就是必需的)并且您不能更改此行为,因为EF期望强制执行关系. (2认同)
  • @AlexK.:我忘记了过去我们有类似的问题和答案:http://stackoverflow.com/a/8539616/270591.答案并不令人满意,但它表明Include的JOINS类型显然是一个复杂的主题,历史悠久,并且经历了从EF版本到版本的一些变化. (2认同)