entity-framework - EF Core,从 netcore2.2 更新到 netcore3.1 后出现无效的列名异常
问题描述
由于我已经从 .netcore2.2 更新到 .netcore3.1,我面临着新的奇怪异常“无效的列名 'TenantTemplateTypeID 1 '”。请不要使用不应该出现在这里的“1”。代码中的任何地方都没有 TenantTemplateTypeID1,所以我假设它是由 EF 核心生成的。
EF核心版本:3.1.1
例外:
Exception: Invalid column name 'TenantTemplateTypeID1'.
Invalid column name 'TenantTemplateTypeID1'.
Invalid column name 'TenantTemplateTypeID1'.
Invalid column name 'TenantTemplateTypeID1'.
StactTrace: at Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at Microsoft.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at Microsoft.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
at Microsoft.Data.SqlClient.SqlDataReader.get_MetaData()
询问:
var t = engineCtx.TenantTemplates
.AsNoTracking()
.Include(tt => tt.TenantTemplateParameters)
.Include(tt => tt.TenantTemplateStyles)
.FirstOrDefault(tt => tt.TenantTemplateTypeID == tenantTemplateTypeID);
数据库上下文
modelBuilder.Entity<Db.Model.TenantTemplate>(entity =>
{
entity.HasKey(e => e.TenantTemplateTypeID)
.HasName("PK_TenantTemplate_TenantTemplateTypeID");
entity.ToTable("TenantTemplates", "templateEngine");
entity.Property(e => e.TenantTemplateTypeID)
.HasColumnName("TenantTemplateTypeId");
//... not related rows removed
entity.HasMany(e => e.TenantTemplateParameters)
.WithOne(e => e.TenantTemplate)
.HasConstraintName("FK_TenantTemplate_TenantTemplateParameters")
.OnDelete(DeleteBehavior.Restrict);
entity.HasMany(e => e.TenantTemplateStyles)
.WithOne(e => e.TenantTemplate)
.HasConstraintName("FK_TenantTemplate_TenantTemplateStyles")
.OnDelete(DeleteBehavior.Restrict);
});
DB 模型只包含没有任何属性的属性。
public partial class TenantTemplate
{
public long TenantTemplateTypeID { get; set; }
// not related rows removed
public virtual ICollection<TenantTemplateParameter> TenantTemplateParameters { get; set; }
public virtual ICollection<TenantTemplateStyle> TenantTemplateStyles { get; set; }
}
// TenantTemplateStyle is exacly the same (just PK has a different name)
public class TenantTemplateParameter
{
public long TenantTemplateParameterID { get; set; }
public long TenantTemplateTypeID { get; set; }
// rows removed
public virtual TenantTemplate TenantTemplate { get; set; }
}
有谁知道一些overround?谢谢...
解决方案
我很确定这是由以下 EF Core 3.0 重大更改引起的 -外键属性约定不再匹配与主体属性相同的名称。
根据该规则,TenantTemplateTypeID
inTenantTemplateParameter
不被视为 FK 名称。
奇怪的是,根据外键影子属性中解释的规则,它同时是默认的常规 FK 名称:
该属性将被命名为
<navigation property name><principal key property name
> (指向主体实体的依赖实体上的导航用于命名)。如果主键属性名称包含导航属性的名称,则名称将为<principal key property name>
. 如果从属实体上没有导航属性,则使用主体类型名称代替它。
由于该名称已由“非 FK”属性保留,因此常规名称生成器将索引添加到默认常规名称,因此观察到的行为。
我认为这是当前 EF Core 实现的错误/缺陷。解决方法/解决方案当然是显式映射 FK 属性,例如
entity.HasMany(e => e.TenantTemplateParameters)
.WithOne(e => e.TenantTemplate)
.HasForeignKey(e => e.TenantTemplateTypeID) // <--
.HasConstraintName("FK_TenantTemplate_TenantTemplateParameters")
.OnDelete(DeleteBehavior.Restrict);
TenantTemplateStyle
如果使用相同的命名约定,则其他关系(与)类似。
推荐阅读
- ruby - Ruby fork 进程时如何检测或记录(ubuntu 14.04)?
- java - Android自定义DialogFragment问题
- excel-formula - 如何在excel中组合多个COUNTIF公式
- excel - 在 Vlookup 公式中使用赋值
- next.js - Gatsby 或 NextJS 用于电子商务复杂网站
- svelte - 在苗条上安装美人鱼
- kubernetes-helm - 将字符串转换为 YAML 映射
- python - 如何在python中的两个数据框之间添加列并按条件填充它的值
- c++ - Boolean stop signal between threads
- google-cloud-platform - 停止和启动 vm 实例后 GCP 的 SSH 终端不工作