【问题标题】:Non-default foreign key relationship非默认外键关系
【发布时间】:2021-03-13 12:16:40
【问题描述】:

在 EF-Core 3.1 中工作 - 尝试在简单导航属性上配置外键关系。 依赖实体中的主键不是整数,也没有默认的“ID”名称。

我不想使用默认的整数自动增量 ID 列 - 我知道这些可以正常工作,但它也应该以这种方式工作,它看起来真的很简单,但我找不到它应该如何工作。

下面是一个简化的例子:

    public class Customer
    {
        public int ID { get; set; }
        public String Name { get; set; }
        public Language Lang { get; set; }
    }

    public class Language
    {
        public String ISOCode { get; set; }
        public String Name { get; set; }
    }

Fluent API 配置:

    public void Configure(EntityTypeBuilder<Language> builder)
    {
        builder.HasKey(c => c.ISOCode);
        builder.Property(c => c.ISOCode).HasMaxLength(5).IsRequired();
        builder.Property(c => c.Name).HasMaxLength(64).IsRequired();
    }

使用该代码添加迁移时不会出现错误,并且生成的 桌子看起来还不错。 但是,针对上述的查询总是返回“Lang”属性的空值。 比如下面的简单查询

        dbContext.Customers
                 .Where(x => x.ID == 4701)
                 .Include(x => x.Lang)
                 .FirstOrDefault();

可以找到正确的客户,但没有填充“Lang”属性,它是 总是空的。我检查了为上述查询生成的 SQL,这没问题 - 我可以在 SQL 服务器中运行该查询,它确实会显示“Lang”的值。

但 EF Core 在数据库返回时似乎找不到该值。

我知道 EF Core 按约定进行配置,我的列名和类型不是预期的。

所以我尝试在 fluent API 中配置外键,但似乎没有可以编译的方法组合。我从 Microsoft 找到的关于“关系”的文档只是省略了简单参考导航属性的这种情况。他们似乎认为您必须将另一个属性放入指向“客户”的依赖实体(语言)中,这对我来说毫无意义。

我在网上找到的任何示例似乎都适用于 EF-Core 5 或 EF-Core 2 - 它们不适用于 EF- 核心 3.1。

我应该能够配置外键属性。但我似乎不能自己做到这一点,我必须配置关系并将外键添加到它上面 - 但是如何? 它应该是这样的:

        builder.HasOne(c => c.ISOCode)
               .WithOne(c => ???)
               .HasForeignKey("ISOCode")

看起来 WithOne 必须具有某种指向客户的属性 - 但这不是一对一的关系,这甚至不是我想要的吗?

或者问题只是完全不同的东西?

【问题讨论】:

  • Language 不是依赖的,而是主体的。依赖 == 引用,主要 == 引用。使用原始代码,无需配置 FK(以及一对关系) - 按照约定,EFC 应该在 Customer 表中创建 LangISOCode 列并设置为 FK引用Language 表PK。你能确认一下吗?
  • 是的,该列已创建,并且为上述查询生成的 SQL 引用了正确的列 - 正如我所说,生成的 SQL 查询是完全正确的,但在 C# 中该值没有出现。
  • 确保 FK 和 PK 值精确匹配。 EF Core 客户端部分区分大小写,因此即使数据库正确连接了两个表,它也可能返回 null(不匹配),以防键因大小写而异。

标签: entity-framework-core


【解决方案1】:

解决了 - 与外键配置无关。

作为记录 - Ivan Stoev 在上面的评论中所说的是完全正确的 - 在这种情况下,EF Core 可以自动正确地计算出关系和密钥,而无需添加任何配置。

原来我的问题是由我测试它的方式引起的。

我在 NUnit 测试方法中插入了测试数据,然后使用相同的 DataContext 实例来查询它。似乎这行不通。一旦我使用了 2 个 DataContext 实例 - 一个用于创建数据,一个用于进行查询,查询就开始正常工作,返回所需的所有值。

此时我不知道为什么会这样,如果它是一个错误等。但是我遇到的问题已经解决了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-15
    • 1970-01-01
    • 1970-01-01
    • 2014-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多