EF Core 一对一零关系不在结果中返回数据
EF Core one to one to zero relationship not returning data in result
我目前正在使用带有代码优先迁移的 EF Core 2.2.1 将现有数据库设计迁移到新应用程序中。我们当前的设计有一个主 table,然后可以有多个子 table 具有相同的共享主键。我查看了 this similar question 并尝试在那里复制答案,但在结果中显示数据方面运气不佳。
简化的架构看起来有点像下面这样:
public class Root
{
public enum SubEntityType
{
A,
B,
C,
D
}
public Guid Id { get; set; }
public SubEntityType Type { get; set; }
public virtual TypeA A { get; set; }
public virtual TypeB B { get; set; }
public virtual TypeC C { get; set; }
public virtual TypeD D { get; set; }
}
public class TypeA
{
public Guid Id { get; set; }
public virtual Root Root { get; set; }
public int A { get; set; }
}
public class TypeB
{
public Guid Id { get; set; }
public virtual Root Root { get; set; }
public Guid B { get; set; }
}
public class TypeC
{
public Guid Id { get; set; }
public virtual Root Root { get; set; }
public string C { get; set; }
}
public class TypeD
{
public Guid Id { get; set; }
public virtual Root Root { get; set; }
public bool D { get; set; }
}
然后我使用 fluent api 建立关系如下:
builder.Entity<Models.Root>()
.HasOne( e => e.A )
.WithOne( e => e.Root )
.HasForeignKey<Models.TypeA>( e => e.Id );
builder.Entity<Models.Root>()
.HasOne( e => e.B )
.WithOne( e => e.Root )
.HasForeignKey<Models.TypeB>( e => e.Id );
builder.Entity<Models.Root>()
.HasOne( e => e.C )
.WithOne( e => e.Root )
.HasForeignKey<Models.TypeC>( e => e.Id );
builder.Entity<Models.Root>()
.HasOne( e => e.D )
.WithOne( e => e.Root )
.HasForeignKey<Models.TypeD>( e => e.Id );
在我尝试添加数据之前,它似乎运行良好。我用一些虚拟数据创建根条目。在 root
table:
Id Type
6f0f24cf-fbd7-4b4d-8059-0810daaf5460 1
在TypeA
table:
Id A
6f0f24cf-fbd7-4b4d-8059-0810daaf5460 12
一切都很好,看起来不错。当我这样查询时:
var result = ctx.Root.First();
我得到以下结果(很抱歉格式化,试图让它更好一点):
Name Value
result {Test.Models.Root}
A null
B null
C null
D null
Id {6f0f24cf-fbd7-4b4d-8059-0810daaf5460}
Type B
不应该 A
填充 Test.Models.TypeA
对象并将 A
设置为 12
?这是 EF 所做的优化,我需要按需加载 A
还是我设置的关系不正确?或者,我的方法在这里是错误的吗?我应该以不同的方式来做吗?
在 Entity Framework Core 中,虚拟导航属性不会自动加载,除非您 Configure Lazy Loading 或将 Eager Loading
与 Include
一起使用。
所以请按如下方式编写您的查询:
var result = ctx.Root.Include(r => r.TypeA).Include(r => r.TypeB)
.Include(r => r.TypeC).Include(r => r.TypeD).FirstOrDefault();
现在 Root
将关联 TypeA
、TypeB
、TypeC
和 TypeD
。
我目前正在使用带有代码优先迁移的 EF Core 2.2.1 将现有数据库设计迁移到新应用程序中。我们当前的设计有一个主 table,然后可以有多个子 table 具有相同的共享主键。我查看了 this similar question 并尝试在那里复制答案,但在结果中显示数据方面运气不佳。
简化的架构看起来有点像下面这样:
public class Root
{
public enum SubEntityType
{
A,
B,
C,
D
}
public Guid Id { get; set; }
public SubEntityType Type { get; set; }
public virtual TypeA A { get; set; }
public virtual TypeB B { get; set; }
public virtual TypeC C { get; set; }
public virtual TypeD D { get; set; }
}
public class TypeA
{
public Guid Id { get; set; }
public virtual Root Root { get; set; }
public int A { get; set; }
}
public class TypeB
{
public Guid Id { get; set; }
public virtual Root Root { get; set; }
public Guid B { get; set; }
}
public class TypeC
{
public Guid Id { get; set; }
public virtual Root Root { get; set; }
public string C { get; set; }
}
public class TypeD
{
public Guid Id { get; set; }
public virtual Root Root { get; set; }
public bool D { get; set; }
}
然后我使用 fluent api 建立关系如下:
builder.Entity<Models.Root>()
.HasOne( e => e.A )
.WithOne( e => e.Root )
.HasForeignKey<Models.TypeA>( e => e.Id );
builder.Entity<Models.Root>()
.HasOne( e => e.B )
.WithOne( e => e.Root )
.HasForeignKey<Models.TypeB>( e => e.Id );
builder.Entity<Models.Root>()
.HasOne( e => e.C )
.WithOne( e => e.Root )
.HasForeignKey<Models.TypeC>( e => e.Id );
builder.Entity<Models.Root>()
.HasOne( e => e.D )
.WithOne( e => e.Root )
.HasForeignKey<Models.TypeD>( e => e.Id );
在我尝试添加数据之前,它似乎运行良好。我用一些虚拟数据创建根条目。在 root
table:
Id Type
6f0f24cf-fbd7-4b4d-8059-0810daaf5460 1
在TypeA
table:
Id A
6f0f24cf-fbd7-4b4d-8059-0810daaf5460 12
一切都很好,看起来不错。当我这样查询时:
var result = ctx.Root.First();
我得到以下结果(很抱歉格式化,试图让它更好一点):
Name Value
result {Test.Models.Root}
A null
B null
C null
D null
Id {6f0f24cf-fbd7-4b4d-8059-0810daaf5460}
Type B
不应该 A
填充 Test.Models.TypeA
对象并将 A
设置为 12
?这是 EF 所做的优化,我需要按需加载 A
还是我设置的关系不正确?或者,我的方法在这里是错误的吗?我应该以不同的方式来做吗?
在 Entity Framework Core 中,虚拟导航属性不会自动加载,除非您 Configure Lazy Loading 或将 Eager Loading
与 Include
一起使用。
所以请按如下方式编写您的查询:
var result = ctx.Root.Include(r => r.TypeA).Include(r => r.TypeB)
.Include(r => r.TypeC).Include(r => r.TypeD).FirstOrDefault();
现在 Root
将关联 TypeA
、TypeB
、TypeC
和 TypeD
。