【问题标题】:SQLException: Invalid column nameSQLException: 无效的列名
【发布时间】:2013-03-31 19:03:54
【问题描述】:

我最近使用 EF Reverse Engineer Code First 将现有数据库转换为代码。在完善了大部分结果之后,我开始编写测试。我当前遇到的错误是尝试访问名为“Element_ElementCode”的列名,但是不存在这样的列。
为了确定这一点,我对我的整个项目进行了搜索,以避免意外声明它的可能性。

Find all "Element_ElementCode", Subfolders, Find Results 1, Entire Solution, ""
Matching lines: 0    Matching files: 0    Total files searched: 120

具体错误如下:

System.Data.SqlClient.SqlException: Invalid column name 'Element_ElementCode'.

无效的列名“Element_ElementCode”重复了 10-15 次,堆栈跟踪没有提供任何线索。

当执行包含检索数据的表达式并对其执行一些断言的测试时会发生此异常。

var doos = (dbContext.Elementen.Where(d => d.ElementCode == "DOOS9001")).FirstOrDefault();

这是来自 SQL Server 本身的查询的结果:

Element(在Element.cs内)有以下字段:

ElementCode
Doelgroep
Type
Omschrijving
Titel

元素的映射如下:

public class ElementenMap : EntityTypeConfiguration<Element> {
        public ElementenMap() {

            // Primary Key
            this.HasKey(t => t.ElementCode);

            // Properties
            this.Property(t => t.ElementCode)
                .IsRequired()
                .HasMaxLength(255);

            this.Property(t => t.Type)
                .HasMaxLength(31);

            this.Property(t => t.Doelgroep)
                .HasMaxLength(255);

            this.Property(t => t.Omschrijving)
                .HasMaxLength(255);

            this.Property(t => t.Titel)
                .HasMaxLength(255);

            // Table & Column Mappings
            this.ToTable("Elementen");
            this.Property(t => t.ElementCode).HasColumnName("ElementCode");
            this.Property(t => t.Type).HasColumnName("Type");
            this.Property(t => t.Doelgroep).HasColumnName("Doelgroep");
            this.Property(t => t.Omschrijving).HasColumnName("Omschrijving");
            this.Property(t => t.Titel).HasColumnName("Titel");

            // Relationships
            this.HasMany(t => t.Kernwoorden)
                .WithRequired(t => t.Element)
                .Map(m => m.ToTable("Kernwoorden"));
        }
    }

此外:我确定该数据库已被访问,因为对同一数据库内不同表的其他测试成功。

我已尝试提供尽可能多的相关信息,如果我忘记了来源,请告诉我。为什么它试图访问名为Element_ElementCode 的列?是否可能是我忘记关闭的约定(我已经不得不关闭 PluralizingTableNameConvention)?

我应该寻找什么方向?

编辑:

Kernwood.cs

public class Kernwoord {
        public string ElementCode { get; set; }

        public string KernwoordString { get; set; }

        public virtual Element Element { get; set; }
    }

Element.cs

public partial class Element {
        public Element() {
            this.LeertrajectElementen = new List<LeertrajectElement>();
            this.Kernwoorden = new List<Kernwoord>();
        }

        public string ElementCode { get; set; }

        public string Type { get; set; }

        public string Doelgroep { get; set; }

        public string Omschrijving { get; set; }

        public string Titel { get; set; }

        public virtual Casus Casus { get; set; }

        public virtual Document Document { get; set; }

        public virtual Doos Doos { get; set; }

        public virtual ICollection<LeertrajectElement> LeertrajectElementen { get; set; }

        public virtual StellingenSpel StellingenSpel { get; set; }

        public virtual ICollection<Kernwoord> Kernwoorden { get; set; }
    }

LeertrajectElementenMap.cs sn-p:

 this.HasRequired(t => t.Element)
     .WithMany(t => t.LeertrajectElementen)
     .HasForeignKey(d => d.ElementCode);

编辑:

通过修复现有的继承问题解决了问题。

【问题讨论】:

  • 为什么要映射this.Property(t =&gt; t.ElementCode).HasColumnName("ElementCode");.Map(m =&gt; m.ToTable("Kernwoorden"));。我建议放弃所有“手动”命名(无论如何都是一样的)并尝试不使用它。你在那里做的“太多”了——你让 EF 感到困惑:)
  • 没有它没有任何区别,但我已将其调整为类似的(但仍然不是解决方案),如下面的 cmets 中建议的那样。请注意,这是由 EF 自动生成的,它不应该混淆自己!
  • 拥有一个我们可以快速测试的完整模型会更容易
  • pastebin.com/DgVws3yX 我相信这些都是使示例工作所需的所有类。

标签: c# sql entity-framework


【解决方案1】:

您没有指定关系的外键列名。应该是:

this.HasMany(t => t.Kernwoorden)
    .WithRequired(t => t.Element)
    .Map(m => m.MapKey("ElementCode")); // FK column name in Kernwoorden table

或者,如果您在Kernwoorden 类中有一个外键属性 ElementCode

this.HasMany(t => t.Kernwoorden)
    .WithRequired(t => t.Element)
    .HasForeignKey(t => t.ElementCode);

【讨论】:

  • 这并没有什么不同。你确定这是我应该调查的地方吗? Kernwoorden 表仅包含 ElementCodeKernwoord 列,当我查看数据库图时,我可以看到它们与 ElementCode 上的 FK 链接在一起。
  • @JeroenVannevel:嗯,你必须在某处告诉 EF Kernwoorden 表中的ElementCode FK,否则它会按照约定假定 FK 列名是“NavigationPropertyNameInDependent + 下划线 + PKNameInPrincipial”如果您在 Kernvoorden 类中有导航属性 Element,则为 Element_ElementCode。如果您可以显示 KernvoordenElement 类及其键和导航属性,这可能会有所帮助。
  • 我已使用请求的信息编辑了我的帖子。请注意,由于我正在编辑由 EF Code First 生成的代码,因此仍有一些问题需要解决。出于某种原因,EF 将每个指向 Element 类的链接转换为链接类的属性。 Element 本身应该是一个抽象类并包含一些属性。其他类将从这里继承并添加自己的属性。目前,它们都被翻译为具有属性Element。您认为这可能是问题所在吗?
  • @JeroenVannevel:还有很多其他导航属性可能会导致该问题,例如LeertrajectElementen。您是否为此关系指定了映射?如果LeertrajectElement 具有反向导航属性Element 和FK ElementCode,则问题可能由此产生。顺便说一句:您的模型类中显然有 FK 作为属性,那么您需要使用 HasForeignKey 进行第二种映射。
  • ElementenMap 内部没有到LeertrajectElementen 的映射,但LeertrajectElementenMap 内部有一个链接,我将使用此代码编辑上面的帖子。这足够了吗,还是应该在ElementenMap 中也有定义的关系? Element 应该能够独立存在,但 LeertrajectElement 只能作为 ElementLeertraject 之间的链接存在。
【解决方案2】:

关于类型有一个约定。

例如,如果您有一位客户,而该客户只有一个地址,并且该地址有一个邮政编码。

然后它将生成一个包含字段 Adress_Postcode 的表 Customer。

在您的情况下,您的类名和表名不同,因此它将元素类型放入表 Elementen。

【讨论】:

  • 你知道我应该为此禁用什么约定吗?
  • 尝试将您的班级重命名为与您的表格相同
  • 如果没有其他选择,我会求助于这个(老实说这会让我感到惊讶)
  • 我查看了约定列表,但找不到任何符合我的问题的约定。我忽略了吗?当然,我不可能将我的类调整为它们的复数形式以匹配数据库,考虑到编写单数类和复数表名是很常见的(据我所知)。 msdn.microsoft.com/en-us/library/…
  • 奇点功能只支持英文
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-29
  • 2020-02-23
  • 1970-01-01
  • 2020-09-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多