【问题标题】:EF6 Invalid Column Name Member_IDEF6 无效的列名 Member_ID
【发布时间】:2017-01-18 21:04:55
【问题描述】:

我已多次看到此错误,原因始终是外键设置错误。但在这种情况下,我只是看不到问题所在。

这个测试:

    [TestMethod]
    [TestCategory("Integration")]
    public void DataModelMemberNoteBuilds() {

        _context.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);

        var sut = _context.MemberNotes.FirstOrDefault();

        if (sut == null) {
            Assert.Inconclusive("return null");
        }

        Assert.IsInstanceOfType(sut, typeof(Domain.Members.Note));

    }

抛出此异常:

System.Data.SqlClient.SqlException:列名“Member_ID”无效。

这是我正在为其构建模型的 POCO:

public class Note
{
    public int ID { get; set; }

    public int MemberID { get; set; }
    public DateTime Timestamp { get; set; }
    public int EnteredByEmployeeID { get;  set; }
    public string Subject { get; set; }
    public string Body { get; set; }
    public bool IsActiveHotnote { get; set; }

    public virtual Member Member { get; set; }
    public virtual Employees.Employee EnteredByEmployee { get; set; }

}

表格(不是代码优先生成的):

CREATE TABLE [dbo].[MemberNotes](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [DateCreated] [datetime2](7) NOT NULL,
    [rv] [timestamp] NOT NULL,
    [MemberID] [int] NOT NULL,
    [NoteTimestamp] [datetime2](7) NOT NULL,
    [NoteEnteredByEmployeeID] [int] NOT NULL,
    [NoteSubject] [nvarchar](255) NULL,
    [NoteBody] [nvarchar](2000) NOT NULL,
    [NoteIsActiveHotnote] [bit] NOT NULL,

    PRIMARY KEY CLUSTERED ([ID] ASC) WITH (
        PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON
    ) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[MemberNotes] ADD  DEFAULT (getdate()) FOR [DateCreated]
GO
ALTER TABLE [dbo].[MemberNotes] ADD  DEFAULT (getdate()) FOR [NoteTimestamp]
GO
ALTER TABLE [dbo].[MemberNotes] ADD  DEFAULT ((0)) FOR [NoteIsActiveHotnote]
GO
ALTER TABLE [dbo].[MemberNotes]  WITH CHECK ADD FOREIGN KEY([MemberID])
REFERENCES [dbo].[Members] ([MemberID])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[MemberNotes]  WITH CHECK ADD FOREIGN KEY([NoteEnteredByEmployeeID])
REFERENCES [dbo].[Employees] ([EmployeeID])
ON UPDATE CASCADE
    -- <<<<<<<<<<<<<< NOTE ON DELETE NO ACTION <<<<<<<<<<<<<<<<<
GO

模型是这样构建的:

        mb.Entity<Note>().ToTable("MemberNotes");
        mb.Entity<Note>().Property(x => x.Body).HasColumnName("NoteBody");
        mb.Entity<Note>().Property(x => x.EnteredByEmployeeID).HasColumnName("NoteEnteredByEmployeeID");
        mb.Entity<Note>().Property(x => x.IsActiveHotnote).HasColumnName("NoteIsActiveHotnote");
        mb.Entity<Note>().Property(x => x.Subject).HasColumnName("NoteSubject");
        mb.Entity<Note>().Property(x => x.Timestamp).HasColumnName("NoteTimestamp");
        mb.Entity<Note>()
            .HasRequired(x => x.Member)
            .WithMany(x => x.Notes)
            .HasForeignKey(x => x.MemberID);
        mb.Entity<Note>()
            .HasRequired(x => x.EnteredByEmployee)
            .WithMany(x => x.EnteredMemberNotes)
            .HasForeignKey(x => x.EnteredByEmployeeID);

仅有的两个相关实体是MemberEmployee,它们的ICollections 是这样的:

// Member.cs
public virtual ICollection<Note> Notes { get; set; } 

// Employee.cs
public virtual ICollection<Members.Note> EnteredMemberNotes { get; set; }

来自测试的 EF 查询输出 (_context.MembersNotes.FirstOrDefault()):

SELECT TOP (1) 
    [c].[ID] AS [ID], 
    [c].[MemberID] AS [MemberID], 
    [c].[NoteTimestamp] AS [NoteTimestamp], 
    [c].[NoteEnteredByEmployeeID] AS [NoteEnteredByEmployeeID], 
    [c].[NoteSubject] AS [NoteSubject], 
    [c].[NoteBody] AS [NoteBody], 
    [c].[NoteIsActiveHotnote] AS [NoteIsActiveHotnote], 
    [c].[Member_ID] AS [Member_ID]
    FROM [dbo].[MemberNotes] AS [c]

谁能看到Member_ID 来自哪里?我不知所措。谢谢

【问题讨论】:

  • 根本无法从 EF6 生成 SQL 查询。闻起来像 EF Core。
  • 您可以尝试用ForeignKey attribute 装饰您的Member 属性吗?
  • @IvanStoev EF 6.1.3 准确地说。不知道为什么你说这个查询不能从 EF6 生成(它是我输出的复制/粘贴,我很确定我没有使用 EF Core)。 Michael - 不,我宁愿保留 FluentAPI 驱动的所有内容,而不是注释。
  • 可能是您正在配置 EF6 上下文,但实际上您使用的是 EF-core 上下文?这确实不是来自 SQL-Server 查询提供程序的 EF6 生成的 SQL。
  • @GertArnold - 我真的不这么认为。我从未使用过 EF Core,并且此模型构建器/上下文与我使用了几个月的其他十几个实体组合在一起,没有出现任何问题。它全部包含在一个“数据”项目中,并且该项目有两个 EF 引用(参见链接)。这与所有其他工作模型/测试所来自的_context 相同。 imgur.com/a/r7rLi

标签: c# entity-framework-6


【解决方案1】:

找到了。

我的 Member.cs 类有一个公共只读属性,它根据 ICollection&lt;Note&gt; 中的过滤内容返回 List&lt;Note&gt;

    public List<Note> Hotnotes {
        get
        {
            if (Notes == null) {
                return new List<Note>();
            }
            return Notes.Where(x => x.IsActiveHotnote).OrderByDescending(x => x.Timestamp).ToList();
        }
    }

我没有告诉 EF 忽略这个属性。它正在读取类型并将属性作为附加的关系/导航属性。

将其放入模型构建器可以解决问题:

mb.Entity<Member>().Ignore(x => x.Hotnotes);

感谢您的关注,希望有一天这对其他可怜的草皮有所帮助。

【讨论】:

  • 酷。所以我在上一条评论中是对的 你确定你的 Member 类中没有其他 ICollection&lt;Note&gt; 吗? :)
  • @IvanStoev 确实是你!发表一个答案,我很乐意给你信用(我应该发布完整的会员课程,但我认为这个问题太长了,并且忘记了看似无关的属性可能是多么敏感......)跨度>
  • 呵呵,我们每个人有时都会遇到这种情况:)你的回答就足够了,不需要信用,我很高兴问题得到了解决。编码愉快。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-27
相关资源
最近更新 更多