我正在使用Entity Framework Core(EF Core)工作,遇到了与延迟加载和继承有关的问题。我已经定义了以下实体类:
在我的代码中,我使用
以下是我在
然而,当我检索一个
输出显示,在aPool中的Profile为空,而实际上不应该为空。而在bPool中的Profile正常工作。 在这两种情况下,AProfileId和BProfileId字段都有值。
我还尝试了另一种方式。我尝试将aProfile添加到aPool.Profile,并将aPool添加到context.Pools,但引发了以下错误:
System.InvalidOperationException:“无法将实体类型“AProfile”的实例跟踪为实体类型“BProfile”,因为这两个类型不在同一层次结构中。”
附加信息:
- .NET 6.0 - Entity Framework Core版本:6.0.21 - 数据库提供程序:Microsoft.EntityFrameworkCore.SqlServer 6.0.19 - EF Core工具版本:Microsoft.EntityFrameworkCore.Tools 6.0.19
我想知道为什么会出现这个问题,以及如何解决它。在这种继承情况下,是否需要在EF Core中进行特定的配置,以确保它按预期工作?
我希望这个操作能够将所有的个人资料类型填充到个人资料字段中。
非常感谢您提供任何见解或建议。
新问题:
在实施了涉及代理属性和配置EF Core中继承关系的建议解决方案后,当检索一个Pool对象时,我仍然遇到一个问题。尽管数据库中的外键是正确的,但Pool对象中的Profile字段仍然为空。然而,当单独检索一个Profile时,Profile对象中的关联Pool字段被正确填充。
在EF Core中,是否需要特定的配置或额外的步骤,以确保在检索Pool时,Profile字段会根据外键关系填充相应的Profile类型?
非常感谢您提供的任何见解、建议或替代方法。提前感谢您!
public class Pool
{
public int Id { get; set; }
public virtual Profile? Profile { get; set; }
public int? AProfileId { get; set; }
public int? BProfileId { get; set; }
}
public abstract class Profile
{
public Profile() { }
public int Id { get; set; }
}
public class AProfile : Profile
{
public AProfile() { }
public virtual Pool? Pool { get; set; }
}
public class BProfile : Profile
{
public BProfile() { }
public virtual Pool? Pool { get; set; }
}
public class CProfile : Profile
{
public CProfile() { }
// CProfile does not have the Pool property
}
// Other profile classes
在我的代码中,我使用
HasOne
方法配置了AProfile
和Pool
之间的关系,同样也配置了BProfile
的关系。我还在OnConfiguring
方法中启用了延迟加载。以下是我在
OnModelCreating
方法中配置关系的方式:protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
.
.
.
builder.Entity<AProfile>().HasOne(P => P.Pool).WithOne(Q => Q.Profile as AProfile).HasForeignKey<Pool>(Q => Q.AProfileId).IsRequired(false);
builder.Entity<BProfile>().HasOne(P => P.Pool).WithOne(Q => Q.Profile as BProfile).HasForeignKey<Pool>(Q => Q.BProfileId).IsRequired(false);
}
然而,当我检索一个
Pool
对象并尝试访问其Profile
属性时,我注意到aPool
中的Profile
为空,而它不应该为空。而bPool
中的Profile
正常工作。var aPool = dbContext.Pools.FirstOrDefault(p => p.Id == 1);
Console.WriteLine($"Profile in aPool is \"{aPool.Profile}\"; aPool.AProfileId is {aPool.AProfileId}");
输出显示,在aPool中的Profile为空,而实际上不应该为空。而在bPool中的Profile正常工作。 在这两种情况下,AProfileId和BProfileId字段都有值。
我还尝试了另一种方式。我尝试将aProfile添加到aPool.Profile,并将aPool添加到context.Pools,但引发了以下错误:
System.InvalidOperationException:“无法将实体类型“AProfile”的实例跟踪为实体类型“BProfile”,因为这两个类型不在同一层次结构中。”
附加信息:
- .NET 6.0 - Entity Framework Core版本:6.0.21 - 数据库提供程序:Microsoft.EntityFrameworkCore.SqlServer 6.0.19 - EF Core工具版本:Microsoft.EntityFrameworkCore.Tools 6.0.19
我想知道为什么会出现这个问题,以及如何解决它。在这种继承情况下,是否需要在EF Core中进行特定的配置,以确保它按预期工作?
我希望这个操作能够将所有的个人资料类型填充到个人资料字段中。
非常感谢您提供任何见解或建议。
更新:
感谢@sorosh_sabz解决了这个问题。
解决方案摘要:
为了解决EF Core的延迟加载和继承的初始问题,我在Pool
类中实现了代理属性,以处理不同的Profile
类型。我在OnModelCreating
方法中使用HasOne
和HasForeignKey
配置了模型关系,允许AProfile
和Pool
之间的关联,以及BProfile
和Pool
之间的关联。虽然这个解决方案确保了正确的数据库更新,并适当设置了外键,但在其他地方检索Pool
对象时,Profile
字段为空。
public class Pool
{
public int Id { get; set; }
public Profile? Profile
{
get
{
return ORMAProfileAccessor as Profile ?? ORMBProfileAccessor;
}
set
{
switch (value)
{
case AProfile aProfile:
ORMAProfileAccessor = aProfile;
break;
case BProfile bProfile:
ORMBProfileAccessor = bProfile;
break;
default:
throw new InvalidCastException("Invalid profile type");
}
}
}
internal virtual AProfile? ORMAProfileAccessor { get; set; }
internal virtual BProfile? ORMBProfileAccessor { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<AProfile>().HasOne(P => P.Pool).WithOne(Q => Q.ORMAProfileAccessor).HasForeignKey<Pool>("AProfileId").IsRequired(false);
modelBuilder.Entity<BProfile>().HasOne(P => P.Pool).WithOne(Q => Q.ORMBProfileAccessor).HasForeignKey<Pool>("BProfileId").IsRequired(false);
modelBuilder.Entity<Pool>().Ignore(P => P.Profile);
}
新问题:
在实施了涉及代理属性和配置EF Core中继承关系的建议解决方案后,当检索一个Pool对象时,我仍然遇到一个问题。尽管数据库中的外键是正确的,但Pool对象中的Profile字段仍然为空。然而,当单独检索一个Profile时,Profile对象中的关联Pool字段被正确填充。
在EF Core中,是否需要特定的配置或额外的步骤,以确保在检索Pool时,Profile字段会根据外键关系填充相应的Profile类型?
非常感谢您提供的任何见解、建议或替代方法。提前感谢您!
.NET Framework 6.0
并不存在。.NET Framework
这个术语仅适用于.NET Framework 4.8.1
及以下版本。您正在使用的是.NET 6
,也被称为.NET Core 6
。 - undefined