SQLException: 无效列名

3

最近,我使用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 查询本身的结果:enter image description here 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)?
我该从哪个方向寻找答案?
编辑:
Kernwoord.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代码片段:

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

编辑:

通过修复现有的继承问题,该问题已得到解决。


为什么要映射 this.Property(t => t.ElementCode).HasColumnName("ElementCode");.Map(m => m.ToTable("Kernwoorden"));。我建议放弃所有“手动”命名(它们都是相同的),并尝试不使用它。你在做太多了 - 你让EF感到困惑 :) - NSGaga-mostly-inactive
没有它也没什么区别,但我已经根据下面评论中的建议进行了类似的调整(但仍不是解决方案)。请注意,这是由 EF 自动生成的,它不应该混淆自己! - Jeroen Vannevel
最好有一个完整的模型,这样我们就可以快速测试。 - NSGaga-mostly-inactive
我相信这些都是必需的类,以使示例正常工作。 - Jeroen Vannevel
2个回答

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

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);

@JeroenVannevel:嗯,在某个地方,您必须告诉EF Kernwoorden表中的ElementCode FK,否则它将假定一个FK列名按约定命名,即“NavigationPropertyNameInDependent + underscore + PKNameInPrincipial”,如果您在Kernvoorden类中有一个导航属性Element,那么它将是Element_ElementCode。如果您能展示KernvoordenElement类及其关键和导航属性,可能会有所帮助。 - Slauma
我已经编辑了我的帖子并提供了所需的信息。请注意,由于我正在编辑EF Code First生成的代码,因此仍然存在一些问题需要解决。由于某种原因,EF将每个链接到“Element”类的链接都转换为链接类的属性。一个“Element”本身应该是一个抽象类,并拥有一些属性。其他类将从这个类继承并添加自己的属性。目前,它们都被翻译为具有属性“Element”。您认为这可能是问题所在吗? - Jeroen Vannevel
@JeroenVannevel:还有许多其他导航属性可能会导致问题,例如“LeertrajectElementen”。您是否为此关系指定了映射?如果“LeertrajectElement”具有反向导航属性“Element”和FK“ElementCode”,则问题可能会从那里产生。顺便说一句:您显然已将FK作为模型类中的属性,然后您需要使用“HasForeignKey”的第二种类型的映射。 - Slauma
在调试时,我注意到在我的ElementenSet的结果视图中出现了一个错误:“消息“One or more validation errors were detected during model generation:\r\n\r\n\tSystem.Data.Entity.Edm.EdmAssociationEnd: : 在关系”Element_Kernwoorden“中,角色”Element_Kernwoorden_Target“中的多重性无效。因为从属角色引用键属性,所以从属角色的上限多重性必须为“1”。\r\n" 我猜测错误可能存在于kernwoorden的映射中? - Jeroen Vannevel
@JeroenVannevel:我建议你开始解决你的继承问题(来自你的第三条评论)。Doos类看起来非常奇怪(派生自Element,具有导航属性Element和重写的ElementCode)。这真的是应该看起来像这样吗? - Slauma
显示剩余11条评论

0

关于类型有一个约定。

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

那么它将生成一个名为Customer的表,其中包含一个名为Adress_Postcode的字段。

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


你知道我应该禁用哪个约定吗? - Jeroen Vannevel
尝试将您的类重命名为与表相同的名称。 - Shiraz Bhaiji
如果没有其他选择,我会采取这种方法(说实话,这让我感到惊讶)。 - Jeroen Vannevel
我已经查看了约定列表,但没有找到与我的问题匹配的内容。我是不是忽略了什么?我想应该不可能要调整我的类名为复数形式以匹配数据库,因为按照我所知,将类名写成单数形式而将表名写成复数形式是相当普遍的做法。 http://msdn.microsoft.com/en-us/library/system.data.entity.modelconfiguration.conventions%28v=vs.103%29.aspx - Jeroen Vannevel
奇点功能仅支持英语。 - Shiraz Bhaiji

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接