2017-01-18 5 views
1

Я видел эту ошибку несколько раз, и причина всегда связана с неправильной настройкой внешнего ключа. В этом случае, однако, я просто не вижу проблемы.EF6 Неверное имя столбца Member_ID

Этот тест:

[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: Invalid имя столбца 'member_id'.

Это РоКо Я строю модель для:

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

Только два связанных объекта: Member и Employee, которые имеют ICollection S таким образом:

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

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

EF Запрос Ouput из теста (_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 приходят? Я в недоумении. Спасибо

+0

SQL-запрос просто не может быть сгенерирован из EF6. Пахнет как EF Core. –

+0

Не могли бы вы попытаться украсить свое свойство 'Member'' ForeignKey' [атрибут] (https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.schema.foreignkeyattribute (v = vs.110)) .aspx)? – Michael

+0

@IvanStoev EF 6.1.3, если быть точным. Не уверен, почему вы говорите, что этот запрос не может быть создан из EF6 (это копия/вставка из моего вывода, и я уверен, что я не использую EF Core). Майкл - нет, я бы предпочел сохранить все FluentAPI, а не аннотации. – jleach

ответ

1

Найдено.

Мой Member.cs класс имеет свойство общественного чтения только что возвращает List<Note> основанный на отфильтрованной содержания в 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(); 
     } 
    } 

я забыл сказать EF, чтобы игнорировать это свойство. Он читает тип и получает свойство в качестве дополнительного свойства отношения/навигации.

Подставляя это в модели строитель исправляет проблему:

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

Спасибо за красивый, надеюсь, это поможет какой-нибудь другой бедняга когда-нибудь.

+0

Прохладный. Поэтому я был прав в своем последнем комментарии * Вы уверены, что нет другой 'ICollection ' внутри вашего класса-члена? * :) –

+0

@IvanStoev Действительно вы были! Отправьте ответ, и я буду рад дать вам кредит (я должен был разместить полный класс участников, но я подумал, что вопрос слишком длинный, чтобы начать с него, и забыл, как могут быть тщетные, казалось бы, несвязанные свойства ...) – jleach

+0

Хехе , это случается со всеми нами иногда :) Вы отвечаете достаточно, никаких кредитов не требуется, я рад, что проблема решена. Счастливое кодирование. –