Entity framework 实体框架4.1列名称无效
我有两个表格新闻和新闻评论。我遵守命名规则 结构新闻评论Entity framework 实体框架4.1列名称无效,entity-framework,entity-framework-4,entity-framework-4.1,Entity Framework,Entity Framework 4,Entity Framework 4.1,我有两个表格新闻和新闻评论。我遵守命名规则 结构新闻评论 public class NewsComment : BaseComment { public int NewsId { get; set; } public virtual News News { get; set; } } 但查询返回异常无效的列名“News\u Id”。我知道这个异常在“表不相关”列中创建了什么 CREATE TABLE [dbo].[NewsComments]( [Id] [int]
public class NewsComment : BaseComment
{
public int NewsId { get; set; }
public virtual News News { get; set; }
}
但查询返回异常无效的列名“News\u Id”。我知道这个异常在“表不相关”列中创建了什么
CREATE TABLE [dbo].[NewsComments](
[Id] [int] IDENTITY(1,1) NOT NULL,
[NewsId] [int] NOT NULL,
[Text] [varchar](max) NOT NULL,
[UserId] [int] NOT NULL,
[CommentDate] [datetime] NOT NULL,
[Ip] [varchar](40) NOT NULL, CONSTRAINT [PK_NewsComments] 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]
BaseComment
public abstract class BaseComment : BasePersistentEntity, IComment
{
public int UserId { get; set; }
public virtual BaseUser User { get; set; }
[Display(ResourceType = typeof(FrameworkResurce), Name = "CommentText")]
public string Text { get; set; }
[Display(ResourceType = typeof(FrameworkResurce), Name = "CommentDate")]
public DateTime CommentDate { get; set; }
public string Ip { get; set; }
}
public abstract class BaseContent : BasePersistentEntity
{
[Display(ResourceType = typeof(FrameworkResurce), Name = "Keywords")]
public string Keywords { get; set; }
[Display(ResourceType = typeof(FrameworkResurce), Name = "TitleTranslit")]
public string TitleTranslit { get; set; }
[Required(ErrorMessageResourceType = typeof(FrameworkResurce), ErrorMessageResourceName = "IsTextEmpty")]
[Display(ResourceType = typeof(FrameworkResurce), Name = "Title")]
public string Title { get; set; }
[Display(ResourceType = typeof(FrameworkResurce), Name = "Description")]
public string Description { get; set; }
[Display(ResourceType = typeof(FrameworkResurce), Name = "Contents")]
public string Contents { get; set; }
[Display(ResourceType = typeof(FrameworkResurce), Name = "DatePublish")]
public DateTime DatePublish { get; set; }
[Display(ResourceType = typeof(FrameworkResurce), Name = "AuthorPublish")]
public string AuthorPublish { get; set; }
[Display(ResourceType = typeof(FrameworkResurce), Name = "Author")]
public string Author { get; set; }
[Display(ResourceType = typeof(FrameworkResurce), Name = "AuthorUrl")]
public string AuthorUrl { get; set; }
[Display(ResourceType = typeof(FrameworkResurce), Name = "Views")]
public int Views { get; set; }
[Display(ResourceType = typeof(FrameworkResurce), Name = "Comments")]
public int Comments { get; set; }
[Display(ResourceType = typeof(FrameworkResurce), Name = "IsComment")]
public bool IsComment { get; set; }
[Display(ResourceType = typeof(FrameworkResurce), Name = "SumVote")]
public int SumVote { get; set; }
[Display(ResourceType = typeof(FrameworkResurce), Name = "VoteCount")]
public int VoteCount { get; set; }
[NotMapped]
[Display(ResourceType = typeof(FrameworkResurce), Name = "Rating")]
public double Rating
{
get
{
if (VoteCount > 0)
{
return Math.Round((float)SumVote/VoteCount, 2);
}
return 0;
}
}
}
新闻
public class News : BaseContent
{
[Display(ResourceType = typeof(NewsResurce), Name = "NewsImage")]
public string NewsImage { get; set; }
public virtual ICollection<NewsCommentView> CommentViews { get; set; }
}
[GridAction]
public ActionResult AjaxCommentsBinding()
{
return View(new GridModel<NewsComment>
{
Data = GetComments()
});
}
CREATE VIEW [dbo].[NewsCommentViews]
AS
SELECT dbo.NewsComments.NewsId, dbo.NewsComments.Text, dbo.NewsComments.UserId, dbo.NewsComments.CommentDate, dbo.NewsComments.Ip,
dbo.Roles.RoleName, dbo.Users.UserName, dbo.Users.DateRegistered, dbo.NewsComments.Id, dbo.Users.Avatar
FROM dbo.NewsComments INNER JOIN
dbo.Users ON dbo.NewsComments.UserId = dbo.Users.Id INNER JOIN
dbo.Roles ON dbo.Users.RoleId = dbo.Roles.Id
[Table("NewsCommentViews")]
public class NewsCommentView : NewsComment
{
public string RoleName { get; set; }
public string UserName { get; set; }
public DateTime DateRegistered { get; set; }
public string Avatar { get; set; }
}
查询
private IEnumerable<NewsComment> GetComments()
{
var news = NewsCommentRepository.AllIncluding(c=>c.User,c=>c.News);
return news;
}
private DataRepository<NewsComment> NewsCommentRepository
{
get { return DataRepository<NewsComment>.Repository; }
}
public class DataRepository<T> where T : BasePersistentEntity
{
public static DataRepository<T> Repository
{
get
{
return new DataRepository<T>();
}
}
private readonly SGNContext<T> context = new SGNContext<T>();
public IQueryable<T> All
{
get { return this.context.Table; }
}
public IQueryable<T> AllIncluding(params Expression<Func<T, object>>[] includeProperties)
{
IQueryable<T> query = this.context.Table;
return includeProperties.Aggregate(query, (current, includeProperty) => current.Include(includeProperty));
}
public T Find(int id)
{
return this.context.Table.Find(id);
}
public void InsertOrUpdate(T country)
{
if (country.Id == default(int))
{
// New entity
this.context.Table.Add(country);
Save();
}
else
{
// Existing entity
this.context.Entry(country).State = EntityState.Modified;
Save();
}
}
public void Delete(int id)
{
var country = this.context.Table.Find(id);
this.context.Table.Remove(country);
this.Save();
}
private void Save()
{
this.context.SaveChanges();
}
}
新闻评论视图
public class News : BaseContent
{
[Display(ResourceType = typeof(NewsResurce), Name = "NewsImage")]
public string NewsImage { get; set; }
public virtual ICollection<NewsCommentView> CommentViews { get; set; }
}
[GridAction]
public ActionResult AjaxCommentsBinding()
{
return View(new GridModel<NewsComment>
{
Data = GetComments()
});
}
CREATE VIEW [dbo].[NewsCommentViews]
AS
SELECT dbo.NewsComments.NewsId, dbo.NewsComments.Text, dbo.NewsComments.UserId, dbo.NewsComments.CommentDate, dbo.NewsComments.Ip,
dbo.Roles.RoleName, dbo.Users.UserName, dbo.Users.DateRegistered, dbo.NewsComments.Id, dbo.Users.Avatar
FROM dbo.NewsComments INNER JOIN
dbo.Users ON dbo.NewsComments.UserId = dbo.Users.Id INNER JOIN
dbo.Roles ON dbo.Users.RoleId = dbo.Roles.Id
[Table("NewsCommentViews")]
public class NewsCommentView : NewsComment
{
public string RoleName { get; set; }
public string UserName { get; set; }
public DateTime DateRegistered { get; set; }
public string Avatar { get; set; }
}
您的SQL在用户和id之间没有下划线
从数据库更新EDMX(通过右键单击菜单)并检查映射。问题在于
新闻
和新闻评论视图
之间的关系:关系的一端是新闻。评论视图
集合。但另一端是而不是您可能期望的新闻评论视图.News
。为什么?因为属性News
不是在newcommentview
类上声明的,而是在基类上声明的。现在EF不允许实体参与与导航属性的关系,该属性未在该实体类本身上声明,但仅在基类中声明
因此,因为您没有流畅的映射,EF仅通过约定定义所有关系。会发生什么
声明了一个导航属性News
,并指向CommentViews
类newcommentview
- EF找不到类型为
的反向属性,该属性在News
类中声明为。(有一个,但它在基类中,不算在内。)NewsCommentView
- 因此,EF假设关系的另一端在
类中是未公开的NewsCommentView
- 未公开意味着:EF既没有导航属性也没有外键属性,并且将假定数据库表/view
中必要的外键列将具有标准的常规名称NewsCommentViews
- 此常规名称是
->NameOfEntityClass\u PKPropertyName
News\u Id
NewsId
。因此,EF查询不存在的列News\u Id
,因此出现异常
当MVC视图访问NewsComment.News.CommentViews
时,可能会由于延迟加载而触发此异常
您可以通过在Fluent API中明确指定FK列名来解决此问题(据我所知,没有Fluent映射没有其他方法):
公共类MyContext:DbContext
{
// ...
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Entity()
.HasMany(n=>n.CommentViews)
.WithRequired()//nc.News将引发异常
//因为nc.News在基类中
.Map(a=>a.MapKey(“NewsId”);
}
}
但是注意:请注意
新闻评论视图.News
不是属于新闻.commentview
的关系的另一端。这意味着,如果在News.CommentViews
集合中有newscordview
,则newscordview.News
不会指向该News
对象。另一端不可见且未在模型中暴露。上面的映射只修复了FK列名问题,但不会更改约定将创建的关系(除了可能将关系更改为“必需”而不是“可选”)。能否显示导致异常的查询?也许还有News
和BaseComment
类。在Fluent API中是否有映射代码?能否显示引发异常的查询?接下来的两个问题:1)NewsCommentView的外观如何?2) 您能否准确显示使用查询的代码GetComments()
?它只是一个IQueryable/IEnumerable
,因此查询不会在GetComments
中执行,而是在其他地方执行。请准确地指出引发异常的那一行。模型中的NewsCommentView
类是如何定义的?现在我看到您编辑了问题。您在哪里将属性NewsId映射到(不存在)列News\u Id搜索你的代码。如果已经在代码中更正了输出文件,请尝试删除该文件。