2017-01-18 4 views
1

Ich habe diesen Fehler zigfach gesehen und die Ursache liegt immer an einem falsch konfigurierten Fremdschlüssel-Setup. In diesem Fall kann ich das Problem jedoch nicht sehen.EF6 Ungültiger Spaltenname Member_ID

Dieser Test:

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

    } 

Wirft diese Ausnahme:

System.Data.SqlClient.SqlException: Ungültiger Spaltenname 'member_id'.

Dies ist die POCO Ich baue das Modell für:

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

} 

Die Tabelle (nicht Code-first generiert):

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 

Das Modell ist wie so bauen wird:

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

Die einzigen beiden verbundenen Unternehmen sind Member und Employee, die ICollection s hat als so:

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

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

EF Abfrage ouput aus dem Test (_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] 

jedermann sehen kann, wo die Member_ID herkommt? Ich bin ratlos. Danke

+0

Die SQL-Abfrage kann einfach nicht aus EF6 generiert werden. Riecht wie EF Core. –

+0

Können Sie versuchen, Ihre 'Member' -Eigenschaft mit' ForeignKey' [Attribut] (https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.schema.foreignkeyattribute (v = vs.110) zu dekorieren) .aspx)? – Michael

+0

@IvanStoev EF 6.1.3 um genau zu sein. Nicht sicher, warum Sie diese Abfrage sagen, kann nicht von EF6 generiert werden (es ist ein Kopieren/Einfügen von meiner Ausgabe, und ich bin mir ziemlich sicher, dass ich EF Core nicht verwende). Michael - nein, ich würde lieber alles, was FluentAPI antreibt, lieber behalten als Annotationen. – jleach

Antwort

1

Es gefunden.

Mein Member.cs Klasse verfügt über eine öffentliche schreibgeschützte Eigenschaft, die ein List<Note> auf gefilterten Inhalt basierend kehrt in ICollection<Note>

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

ich vernachlässigte EF zu sagen, diese Eigenschaft zu ignorieren. Es liest den Typ und hebt die Eigenschaft als zusätzliche Relation/Navigationseigenschaft auf.

dies in den Modellbauer Putting behebt das Problem:

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

Dank für das Schauen, hoffentlich eines Tages eine andere arme Sau hilft.

+0

Cool. Also war ich in meinem letzten Kommentar richtig * Bist du sicher, dass es keine gibt andere 'ICollection ' in Ihrem Mitglied Klasse? * :) –

+0

@IvanStoev In der Tat Sie waren! Veröffentlichen Sie eine Antwort und ich werde Ihnen gerne Kredit geben (ich hätte die volle Member-Klasse veröffentlichen sollen, aber ich dachte, die Frage wäre zu lang, um zu vergessen, wie heikel und scheinbar unverwandte Eigenschaften sein könnten ...) – jleach

+0

Hehe manchmal passiert es uns allen :) Du antwortest genug, es wird kein Kredit benötigt, ich bin froh, dass das Problem gelöst ist. Glückliche Kodierung. –

Verwandte Themen