【发布时间】: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(不匹配),以防键因大小写而异。