实体框架失去了关系映射



我在一个小型辅助服务项目中发现了一个问题。我创建了一个代码优先的数据库,如下所示:

public class DBContext : DbContext
{
public DBContext()
{
}
public DBContext(DbContextOptions options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<SubClass>()
.HasOne(t => t.ParentClass)
.WithMany(s => s.Subs);
}
public DbSet<TestClass> TestClasses { get; set; }
public DbSet<SubClass> SubClasses { get; set; }
}
public class TestClass
{
public Guid ID { get; set; }
public string Name { get; set; } = "";
public ICollection<SubClass> Subs { get; set; } = new List<SubClass>();
}
public class SubClass
{
public Guid ID { get; set; }
public string Name { get; set; } = "";
[ForeignKey("ParentClass")]
public Guid? ParentClassID { get; set; }
public TestClass? ParentClass { get; set; }
}

数据库是在启动时创建的。首先,我启动一个线程,将一些数据填充到DB:中

using (var scope = _factory.CreateScope())
{
var _db = scope.ServiceProvider.GetRequiredService<DBContext>();
if (!_db.TestClasses.Any())
{
TestClass cls = new TestClass { Name = "Class1" };
cls.Subs.Add(new SubClass { Name = "SubClass1" });
_db.TestClasses.Add(cls); ;
await _db.SaveChangesAsync();
_logger.LogInformation($"Created items");
cls = new TestClass();
cls = _db.TestClasses.First();
_logger.LogInformation($"Count is: {cls.Subs.Count}");
}
}

这似乎工作得很好,并且记录器返回"0";计数为:1〃;

然后我启动另一个线程,读取数据:

using (var scope = _factory.CreateScope())
{
var _db = scope.ServiceProvider.GetRequiredService<DBContext>();

TestClass cls = _db.TestClasses.First();
_logger.LogInformation($"Second Count is: {cls.Subs.Count}");
}

但是现在Logger返回";第二个计数是:0〃;。列表中没有子类。当我检查数据库时,一切看起来都很好:

TestClass:
ID                                      Name
A1BEB353-D2CB-47BA-500C-08DA8FEADD1A    Class1
Subclass:
ID                                      Name        ParentClassID
46D06860-02D6-4192-867F-08DA8FEADD22    SubClass1   A1BEB353-D2CB-47BA-500C-08DA8FEADD1A

但是当我读出TestClass时,它没有subs。似乎这种关系不知怎么就失去了。有人有想法吗?

如果有帮助的话,下面是我的迁移:

protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "TestClasses",
columns: table => new
{
ID = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Name = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_TestClasses", x => x.ID);
});
migrationBuilder.CreateTable(
name: "SubClasses",
columns: table => new
{
ID = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Name = table.Column<string>(type: "nvarchar(max)", nullable: false),
ParentClassID = table.Column<Guid>(type: "uniqueidentifier", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_SubClasses", x => x.ID);
table.ForeignKey(
name: "FK_SubClasses_TestClasses_ParentClassID",
column: x => x.ParentClassID,
principalTable: "TestClasses",
principalColumn: "ID");
});
migrationBuilder.CreateIndex(
name: "IX_SubClasses_ParentClassID",
table: "SubClasses",
column: "ParentClassID");
}

事实证明,如果第二次提取数据,我必须指定

TestClass cls = _db.TestClasses.Include(c => c.Subs).First();

现在我把潜艇拿出来。但我以前在英孚没有这样做过。这是新的还是某种形式的选择?在我遇到这个问题的ACTUAL项目中,我需要检索一个完整的项树(而不仅仅是一层子项(,我想在代码中引用它们,比如:

LowestClass.Parent.Parent.Topclass.SomeProperty = ...

我必须";包括";所有的?无论如何,要获得下一级别的潜艇似乎并不容易,因为我不能"包括";子集的子集。。。

我以为EF默认使用延迟加载来处理这些事情?看起来它既没有懒惰也没有急于加载,但根本没有。

最新更新