EntityFramework(仅数据注释)关系不解决ID

发布于 2025-01-19 08:13:32 字数 1182 浏览 0 评论 0原文

我有两个班级的关系。

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)上完美运行。当我添加这样的类并稍后从数据库中获取它时(例如在 SaveChangesAsync 之后),我得到了该对象,包括对象 ClassA.Other。

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

只是为了澄清一下,为什么我写 ClassB?其他而不是ClassB其他。这只是代码的简化版本,我很快进行了测试,但在我们的生产环境中,出于性能原因,我们从某些查询中包含/排除某些字段。因此,该属性有可能在某些时候为空。

I have the relationship of two 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>();
}

When I insert an object of ClassA I do it like this:

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

This works perfectly on the live database (Azure SQL DB). When I add the class like this and fetch it from the database later on (e.g. literally after the SaveChangesAsync), I get the object, INCLUDING the object ClassA.Other.

When I run the code on an in-memory DB on the other hand, it does not work! The inserting step works, but does NOT validate if the ID (ClassA.OtherId) exists. This means, I can set the ClassA.OtherId to "12345" without any problems, even if I do not have a single entry of ClassB. If I insert a valid ClassA.OtherId it works as well, but when I fetch the object from the database, ClassA.Other is null.

Just to clarify, why I write ClassB? Other instead of ClassB Other. This is only a simplified version of the code, I tested quickly, but in our production environment, we include/exclude certain fields from certain queries for performance reasons. Therefore, it is possible that the property might be null at certain times.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

牛↙奶布丁 2025-01-26 08:13:32

大多数内存中 Testdouble 在这方面都有一些缺陷,请尝试使用 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);
        }
    }
}

Most In-memory Testdoubles have some flaws in that regard, instead try to use the SQlite Provider, for it behaves more like a real Database

Example for the Configuration:

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

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

    private static void EnsureSqliteTempDatabaseFolderExists(string tempDataBaseFolder)
    {
        if (!Directory.Exists(tempDataBaseFolder))
        {
            Directory.CreateDirectory(tempDataBaseFolder);
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文