不存在的列或属性的列名无效

时间:2017-07-25 05:53:42

标签: sql-server entity-framework

我正在尝试使用Entity Framework将记录保存到SQL Server数据库的Address表中,但是在调用context.SaveChanges时,我得到一个异常,说“更新条目时出错。请参阅细节的内在例外。“检查内部异常后,会显示一条消息“无效的列名'Telephone_TelephoneID'。”

地址表没有“TelephoneID”列。它可能同时有一个,但我们确定我们删除了它的任何痕迹;在Address表的任何键,约束或索引中都没有提到这样的列。地址记录的实体类(我添加到上下文中的实例)没有“TelephoneID”属性。电话表确实有一个“TelephoneID”列,但我不以任何方式涉及它或它的实体类。

这个错误可能来自哪里?提前谢谢......

编辑 - 在调试和观察上下文对象时,我们注意到Addresses属性的计算结果为:

{SELECT 
1 AS [C1], 
[Extent1].[AddressID] AS [AddressID], 
[Extent1].[AddressTypeID] AS [AddressTypeID], 
[Extent1].[City] AS [City], 
[Extent1].[CompanyID] AS [CompanyID], 
[Extent1].[Country] AS [Country], 
[Extent1].[County] AS [County], 
[Extent1].[Extra] AS [Extra], 
[Extent1].[State] AS [State], 
[Extent1].[Street] AS [Street], 
[Extent1].[Zip] AS [Zip], 
[Extent1].[UpdateTimeStampUtc] AS [UpdateTimeStampUtc], 
[Extent1].[UpdateUserGUID] AS [UpdateUserGUID], 
[Extent1].[UpdateUserID] AS [UpdateUserID], 
[Extent1].[Telephone_TelephoneID] AS [Telephone_TelephoneID]
FROM [Sales].[Address] AS [Extent1]}    

我猜这是表格曾经有过这个专栏时遗留下来的。由于我不知道如何创建此查询值或存储位置(解决方案范围内搜索“Telephone_TelephoneID”没有显示),我该如何更正?

2 个答案:

答案 0 :(得分:0)

如果数据库中存在未在模型或模型映射中处理的外键关系,我相信EF将尝试确定(或组成)用于关系的列名。我认为回答问题有助于查看电话和地址表的模型定义。如果数据库中存在未被模型或模型映射捕获的外键关系,则您需要考虑具有以下选项之一的关键字:

  1. 使用FluentApi在模型映射中指定外键

    modelBuilder.Entity<YourTable>()
        .HasForeignKey(c => c.YourForeignKeyId);
    
  2. 使用ForeignKey属性在模型类中指定外键(具有相应的虚拟导航属性)

    [ForeignKey("YourForienKeyColumn")]
    public virtual YourTable YourTable { get; set; }
    

答案 1 :(得分:0)

简而言之,当Address有一个TelephoneID列时,遗留了一些元素,更新模型的实体类解决了这个问题。

有一条线索是关闭的 - 而且我不知道我是如何错过这一点的 - 应该是电话实体类如何拥有这个属性:

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Address> Addresses { get; set; }

当然,如果启用了延迟加载,这将填充具有电话记录的TelephoneID的地址记录的地址对象。我们现在有一个AddressShipInfo类,它有一个AddressID和TelephoneID,并将它们作为外键实现,生成这个代码(&#34; oes&#34;自动写入):

[Table("Sales.AddressShipInfo")]
public partial class AddressShipInfo
{
    ...
    public virtual Address Address { get; set; }

    public virtual Telephone Telephone { get; set; }
}

[Table("Sales.Address")]
public partial class Address
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Address()
    {
        AddressShipInfoes = new HashSet<AddressShipInfo>();
    }
    ...
    public virtual AddressType AddressType { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<AddressShipInfo> AddressShipInfoes { get; set; }
}

[Table("Sales.Telephone")]
public partial class Telephone
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Telephone()
    {
        AddressShipInfoes = new HashSet<AddressShipInfo>();
    }
    ...

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<AddressShipInfo> AddressShipInfoes { get; set; }
}

所以现在,当然,人们可以检索地址或电话,并且延迟(或急切或显式)加载具有引用它的AddressShipInfo记录。最重要的是,Telephone_TelephoneID不再是地址查询的一部分!

感谢所有回复的人,希望这有助于某人。