【问题标题】:EF Core, Invalid column name exception after update from netcore2.2 to netcore3.1EF Core,从 netcore2.2 更新到 netcore3.1 后出现无效的列名异常
【发布时间】:2020-05-19 14:02:12
【问题描述】:

自从我从 .netcore2.2 更新到 .netcore3.1 后,我遇到了新的奇怪异常“无效的列名 'TenantTemplateTypeID1'”。请不要使用不应该出现在这里的“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吗?谢谢...

【问题讨论】:

  • 您能发帖TenantTemplateParameter 或TenantTemplateStyle 课程吗?问题应该就在那里。
  • 问题已更新...

标签: entity-framework entity-framework-core ef-core-3.1


【解决方案1】:

我很确定这是由以下 EF Core 3.0 重大更改引起的 - The foreign key property convention no longer matches same name as the principal property。

根据该规则,TenantTemplateParameter 中的 TenantTemplateTypeID 不被视为 FK 名称。

奇怪的是,它同时是根据Foreign key shadow properties中解释的规则默认的常规FK名称:

该属性将被命名为&lt;navigation property name&gt;&lt;principal key property name>(依赖实体上的导航,指向主体实体,用于命名)。 如果主键属性名称包含导航属性的名称,则名称将只是&lt;principal key property name&gt;。 如果依赖实体上没有导航属性,则使用主体类型名称它的位置。

由于名称已由“非 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)类似。

【讨论】:

    猜你喜欢
    • 2021-12-03
    • 2021-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-20
    • 1970-01-01
    • 2016-09-18
    • 1970-01-01
    相关资源
    最近更新 更多