EntityFramework(仅限数据注释)关系未通过 ID 解析

EntityFramework (Data Annotations only) Relationship not resolving with ID

我有两个 classes 的关系。

class ClassA {
   [Required]
   int Id { get; set; }

   [Required]
   public int OtherId { get; set; }

   [ForeignKey("OtherId")]
   public ClassB? Other{ get; set; }
}
class ClassB {
   [Required]
   int Id { get; set; }

   public IEnumerable<ClassA> Others { get; set; } = new List<ClassA>();
}

当我插入 ClassA 的对象时,我是这样做的:

await this.Context.Set<ClassA>().AddAsync(new ClassA() { OtherId = 2 } );
await this.Context.SaveChangesAsync();

这在实时数据库 (Azure SQL DB) 上完美运行。当我像这样添加 class 并稍后从数据库中获取它时(例如,在 SaveChangesAsync 之后),我得到了对象,包括对象 ClassA.Other.

另一方面,当我 运行 内存数据库上的代码时,它不起作用!插入步骤有效,但不验证 ID (ClassA.OtherId) 是否存在。这意味着,我可以毫无问题地将 ClassA.OtherId 设置为“12345”,即使我没有 ClassB 的单个条目。如果我插入一个有效的 ClassA.OtherId 它也能正常工作,但是当我从数据库中获取对象时,ClassA.Other 为空。

澄清一下,为什么我写 ClassB? Other 而不是 ClassB Other。这只是代码的简化版本,我测试得很快,但在我们的生产环境中,出于性能原因,我们 include/exclude 来自某些查询的某些字段。因此,属性 在某些时候可能为空。

大多数 In-memory Testdoubles 在这方面都有一些缺陷,而不是尝试使用 SQlite Provider,因为它的行为更像一个真正的数据库

配置示例:

public static class EfDbContextSqliteBuilderConfigurationFactory
{
    internal static Action<DbContextOptionsBuilder> GetSqliteDatabaseOption()
    {
        const string tempDataBaseFolder = "Database";
        EnsureSqliteTempDatabaseFolderExists(tempDataBaseFolder);

        return c => c.UseSqlite(new SqliteConnection($"DataSource={tempDataBaseFolder}\{Guid.NewGuid()}.db"));
    }

    private static void EnsureSqliteTempDatabaseFolderExists(string tempDataBaseFolder)
    {
        if (!Directory.Exists(tempDataBaseFolder))
        {
            Directory.CreateDirectory(tempDataBaseFolder);
        }
    }
}