使用C#EF Core返回具有空子级的父级。包括
我们的目标是使用实体框架核心和使用C#EF Core返回具有空子级的父级。包括,c#,entity-framework,entity-framework-core,C#,Entity Framework,Entity Framework Core,我们的目标是使用实体框架核心和.Include(…)扩展方法查询数据库,以返回具有子对象的对象集合,其中一些子对象将为空。 我们有一个带有C#模型项目的表项目和一个带有C#模型位置的表位置 每个项目都有一个或零位置对象,对象如下所示: public class Project { public string LocationId { get; set; } public Location Location { get; set; } } public class Locat
.Include(…)
扩展方法查询数据库,以返回具有子对象的对象集合,其中一些子对象将为空。
我们有一个带有C#模型项目的表项目和一个带有C#模型位置的表位置
每个项目都有一个或零位置对象,对象如下所示:
public class Project
{
public string LocationId { get; set; }
public Location Location { get; set; }
}
public class Location
{
public string LocationId { get; set; }
}
modelBuilder.Entity<Location>(entity =>
{
entity.HasKey(location => location.LocationId);
entity.ToTable("Locations");
});
modelBuilder.Entity<Project>(entity =>
{
entity.HasOne(project => project.Location).WithMany()
.HasForeignKey(x => x.LocationId);
entity.ToTable("Projects");
});
数据库设置如下所示:
public class Project
{
public string LocationId { get; set; }
public Location Location { get; set; }
}
public class Location
{
public string LocationId { get; set; }
}
modelBuilder.Entity<Location>(entity =>
{
entity.HasKey(location => location.LocationId);
entity.ToTable("Locations");
});
modelBuilder.Entity<Project>(entity =>
{
entity.HasOne(project => project.Location).WithMany()
.HasForeignKey(x => x.LocationId);
entity.ToTable("Projects");
});
EF生成的SQL包含一个左连接,而我们期望左外部连接:
结果是只返回具有位置的项目。我们需要所有项目及其位置。
据我所知,.Include(…)
根据外键的可空性决定进行左连接或左外连接:
代码首先根据外键的可空性推断关系的多重性。如果属性可为null,则该关系将注册为可选关系
因为事情不是这样的,所以缺少了一些东西
无论是否填充项目位置,返回所有项目都需要进行哪些修改?
谢谢 在T-SQL中,左连接和左外部连接是相同的。外部关键字是可选的。您提供的查询将返回所有产品,无论它们是否有位置。试试看
有关更多详细信息,请参见:我遇到了这种情况,但生成的SQL是:
INNER JOIN [Blah.[Table] AS [x.Child] ON [x].[ChildId] = [x.Child].[Id]
这确实导致了问题,而问题的左连接也可以(正如其他人所指出的)
那么为什么会发生这种情况呢?我的ChildId
是一个Guid
,我已确保将其设置为Guid?
,因为可空性使其成为可选的
接下来,我尝试将.IsRequired(false)
添加到ChildId
的映射中。这就产生了一个错误,告诉我实际的问题是什么:我在主键中还包含了ChildId
(不必要的)
将其从主键中删除会导致查询更改为左联接
,一切正常。您可以在Include()
之后使用DefaultIfEmpty()
方法
例如:
var projects = dbContext.Projects.Include(x => x.Location).DefaultIfEmpty()...;
也许这只是问题中的一个错误,但“左连接”和“左外部连接”是同一回事。左连接
正是您想要的。有什么问题吗?正如许多人指出的,LEFT JOIN
和LEFT OUTER JOIN
是同义词。我在EF Core中有相同的情况,它在[x].[ChildId]=[x.Child].[Id]上生成内部连接[Blah.[Table]作为[x.Child]
,因此不起作用。如果它看起来像OP问题中的代码段,那就没问题了!这可以起作用,但这也会使返回的集合始终包含一个元素。因此,如果查询通常返回一个空集合,它现在将返回一个包含null
的集合。