entity framework 4.1 invalid column name

后端 未结 2 1146
半阙折子戏
半阙折子戏 2020-12-09 05:43

I have two table News and NewsComments. I followed the rules of naming

structure NewsComments

public class NewsComment : BaseComment
{
    public int         


        
2条回答
  •  轻奢々
    轻奢々 (楼主)
    2020-12-09 06:07

    The problem is in the relationship between News and NewsCommentView: One end of the relationship is the News.CommentViews collection. But the other end is not NewsCommentView.News as you perhaps expect. Why? Because the property News is not declared on the NewsCommentView class but on the base class NewsComment. Now EF doesn't allow that an entity participates in a relationship with a navigation property which is not declared on that entity class itself but only in a base class.

    So, because you don't have Fluent mapping EF defines all relationships only by conventions. What happens?

    • News has a navigation property CommentViews declared and pointing to the NewsCommentView class.
    • EF does not find an inverse property of type News which is declared in the NewsCommentView class. (There is one but it's in the base class, which doesn't count.)
    • So, EF assumes the other end of the relationship is not exposed in the NewsCommentView class.
    • Not exposed means: EF doesn't have a navigation property nor a foreign key property and will assume that the necessary foreign key columns in the database table/view NewsCommentViews will have a standard conventional name.
    • This conventional name is NameOfEntityClass_PKPropertyName -> News_Id

    Your real name in the view is NewsId though. So, EF queries for a column News_Id which doesn't exist, hence the exception.

    The exception is probably triggered due to lazy loading when your MVC-View accesses NewsComment.News.CommentViews.

    You can fix this problem by specifying the FK column name explicitely in Fluent API (as far as I know there no other way without Fluent mapping):

    public class MyContext : DbContext
    {
        // ...
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity()
                .HasMany(n => n.CommentViews)
                .WithRequired() // <- no param because not exposed end of relation,
                                // nc => nc.News would throw an exception
                                // because nc.News is in the base class
                .Map(a => a.MapKey("NewsId"));
        }
    }
    

    But caution: Be aware that NewsCommentView.News is not the other end of the relationship belonging to News.CommentViews. It means that if you have a NewsCommentView in your News.CommentViews collection then NewsCommentView.News does not point back to that News object. The other end is invisible and not exposed in the model. The mapping above just fixes the FK column name problem but doesn't change the relationships which conventions would create anyway (except maybe changing the relationship to required instead of optional).

提交回复
热议问题