【问题标题】:Getting Sql Error: Invalid column name 'PrimaryContact_ContactID'出现 Sql 错误:列名“PrimaryContact_ContactID”无效
【发布时间】:2020-07-30 16:44:30
【问题描述】:

请有人让我摆脱痛苦,让我知道我有/没有做过哪些导致我的代码失败的事情吗?

我首先使用实体​​框架数据库。当我查询实体并请求包含相关实体时,我收到此错误:列名“PrimaryContact_ContactID”无效。在调用Load 方法的那一行会抛出异常。

我正在尝试查询Enterprise 实体之一,并让它也包含Company 实体。

(这是一个复制异常的简化示例)

这是我的实体类:

//Enterprise
public class Enterprise
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int CompanyID { get; set; }

    public virtual Company Company { get; set; }
}

//Company
public class Company
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int PrimaryContactId { get; set; }

    public virtual CompanyContact PrimaryContact { get; set; }
}

//CompanyContact class
public class CompanyContact
{
    public int ContactID { get; set; }
    public string Name { get; set; }
}

这是DataContext

public class DataContext : DbContext
{
    public DbSet<Enterprise> Enterprises { get; set; }
    public DbSet<Company> Companies { get; set; }
    public DbSet<CompanyContact> CompanyContacts { get; set; }

    public DataContext(string connStrName = nameof(DataContext)) : base($"Name={connStrName}")
    {
        Database.SetInitializer<DataContext>(null);
        base.Configuration.ProxyCreationEnabled = false;
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        modelBuilder.Entity<Enterprise>().HasKey(pk => pk.Id);
        modelBuilder.Entity<Enterprise>().Property(i => i.Id)
                                         .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        modelBuilder.Entity<Company>().HasKey(pk => pk.Id);
        modelBuilder.Entity<Company>().Property(i => i.Id)
                                      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        modelBuilder.Entity<Company>().HasOptional(t => t.PrimaryContact);

        modelBuilder.Entity<CompanyContact>().HasKey(pk => pk.ContactID);
        modelBuilder.Entity<CompanyContact>().Property(i => i.ContactID)
                                             .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

    }
}

这是我调用代码的Main 方法。

    static void Main(string[] args)
    {
        try
        {
            using (var ctx = new DataContext())
            {
                ctx.Database.Log = Console.Write;

                var ent = ctx.Enterprises.FirstOrDefault(e => e.Id == 1);

                //Exception thrown on this line.
                ctx.Entry(ent).Reference(e => e.Company).Load();

                Console.WriteLine(ent);
                Console.WriteLine(ent.Company);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }

        Console.ReadLine();
    }

我打开了 EF 日志记录,这是运行代码的输出(为了缩短问题,我没有包含完整的堆栈跟踪):

Opened connection at 2/22/2019 3:43:02 PM -06:00
SELECT TOP (1)
    [Extent1].[Id] AS [Id],
    [Extent1].[Name] AS [Name],
    [Extent1].[CompanyID] AS [CompanyID]
    FROM [dbo].[Enterprise] AS [Extent1]
    WHERE 1 = [Extent1].[Id]
-- Executing at 2/22/2019 3:43:02 PM -06:00
-- Completed in 85 ms with result: SqlDataReader

Closed connection at 2/22/2019 3:43:02 PM -06:00
Opened connection at 2/22/2019 3:43:02 PM -06:00
SELECT
    [Extent1].[Id] AS [Id],
    [Extent1].[Name] AS [Name],
    [Extent1].[PrimaryContactID] AS [PrimaryContactID],
    [Extent1].[PrimaryContact_ContactID] AS [PrimaryContact_ContactID]
    FROM [dbo].[Company] AS [Extent1]
    WHERE [Extent1].[Id] = @EntityKeyValue1
-- EntityKeyValue1: '1' (Type = Int32, IsNullable = false)
-- Executing at 2/22/2019 3:43:02 PM -06:00
-- Failed in 68 ms with error: Invalid column name 'PrimaryContact_ContactID'.

Closed connection at 2/22/2019 3:43:02 PM -06:00
System.Data.Entity.Core.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Invalid column name 'PrimaryContact_ContactID'.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrap

最后,这是数据库架构图:

我确信我一定遗漏了一些基本的东西,但是经过大量搜索后,我无法解决我的问题。

【问题讨论】:

  • 我注意到 Company 表中的 PrimaryContactId 在表中没有大写 ID,但在您的源代码中。这可能是你的问题吗?
  • @Hogan - 感谢您的关注。我更改了代码,但没有解决错误。我很高兴不是这样,因为如果这只是一个大写错误,我会觉得很愚蠢!我将编辑帖子。
  • 修改此行以包含 HasForeignKey 并指定您的 FK 属性 modelBuilder.Entity().HasOptional(t => t.PrimaryContact);
  • @jcruz - HasForeignKey 对我不可用。这仅在 EF Core 中吗?
  • 在上下文之外,我认为您应该将您的 CompanyId 添加到“CompanyContact”而不是 Company 中的 PrimaryContactId,并在 CompanyContact 中保持主要状态。

标签: c# entity-framework-6


【解决方案1】:

您需要为不遵循 EF 默认约定的导航属性强制执行 [ForeignKey] 属性:

public class Company
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int PrimaryContactId { get; set; }

    [ForeignKey(nameof(PrimaryContactId))]
    public virtual CompanyContact PrimaryContact { get; set; }
}

否则,EF 不会将您的 PrimaryContactId 属性识别为 PrimaryContact 的列,而是创建另一个列 PrimaryContact_ContactID

【讨论】:

  • 是的,这行得通,但我还必须删除对 HasOptional 的调用,因为留下它会导致异常:Multiplicity conflicts with the referential constraint in Role
  • 另外,我想我还是要更改我的表以使用更标准的名称Id。再次感谢。
【解决方案2】:

我遇到了同样的错误,正在我的命名约定中寻找解决方案。我尝试了所有可能的约定和技巧,只是为了找出问题的原因是其他原因。

我错误地初始化了我的数据库。我需要 SQLite 的初始化程序(示例用法)。这是我的 CustomContext 中“OnModelCreating”方法的工作示例。

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{   
    var dbi = new SqliteDropCreateDatabaseWhenModelChanges<LogsContext>(modelBuilder);
    DB.SetInitializer<LogsContext>(dbi);
    base.OnModelCreating(modelBuilder);
}

我希望这可以在查找错误时节省一些时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    相关资源
    最近更新 更多