structure d'entité 4.1 nom de colonne non valide
J'ai deux table News et NewsComments. J'ai suivi les règles de nommage
structure NewsComments
public class NewsComment : BaseComment
{
public int NewsId { get; set; }
public virtual News News { get; set; }
}
Mais la requête en retour exception nom de colonne non Valide "News_Id". Je sais ce que cette exception créé lorsque dans le tableau ne sont pas liées colonne.
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; }
}
Nouvelles
public class News : BaseContent
{
[Display(ResourceType = typeof(NewsResurce), Name = "NewsImage")]
public string NewsImage { get; set; }
public virtual ICollection<NewsCommentView> CommentViews { get; set; }
}
BaseContent
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;
}
}
}
Requête
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; }
}
DataRepository
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();
}
}
Utilisé GetComments
[GridAction]
public ActionResult AjaxCommentsBinding()
{
return View(new GridModel<NewsComment>
{
Data = GetComments()
});
}
NewsCommentViews
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
NewsCommentViews
[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; }
}
source d'informationauteur Greg
Vous devez vous connecter pour publier un commentaire.
Le problème est dans la relation entre
News
etNewsCommentView
: Une fin de la relation est laNews.CommentViews
collection. Mais l'autre extrémité est pasNewsCommentView.News
comme vous l'avez peut-être attendre. Pourquoi? Parce que la propriétéNews
n'est pas déclaré sur leNewsCommentView
classe, mais sur la de la classe de baseNewsComment
. Maintenant EF ne permet pas que l'entité qui participe à une relation avec une propriété de navigation qui n'est pas déclaré sur l'entité de la classe elle-même, mais seulement dans une classe de base.Ainsi, parce que vous n'avez pas Couramment la cartographie EF définit toutes les relations que par les conventions. Ce qui se passe?
News
a une propriété de navigationCommentViews
déclaré et pointant vers leNewsCommentView
classe.News
qui est déclaré dans leNewsCommentView
classe. (Il y en a un mais il est dans la classe de base, qui ne compte pas.)NewsCommentView
classe.NewsCommentViews
aura une norme conventionnelle nom.NameOfEntityClass_PKPropertyName
->News_Id
Votre vrai nom dans la vue est
NewsId
. Donc, EF requêtes pour une colonneNews_Id
qui n'existe pas, d'où l'exception.L'exception est probablement déclenchée par le fait que le chargement paresseux lors de votre MVC-Vue accède
NewsComment.News.CommentViews
.Vous pouvez résoudre ce problème en spécifiant le FK nom de la colonne explicitement dans API Fluent (autant que je sache, il n'y pas d'autre moyen, sans parler Couramment mapping):
Mais attention: sachez que
NewsCommentView.News
est pas l'autre bout de la relation appartenant àNews.CommentViews
. Cela signifie que si vous avez unNewsCommentView
dans votreNews.CommentViews
collection puisNewsCommentView.News
ne pas point de retour pour queNews
objet. L'autre extrémité est invisible et n'est pas exposé dans le modèle. La cartographie ci-dessus ne résout le FK nom de la colonne de problème, mais ne modifie pas les relations qui les conventions de créer, de toute façon (sauf peut-être la transformation de la relation à tenus à la place de l'option).Votre SQL n'est pas un trait de soulignement entre l'utilisateur et l'id.
Mise à jour EDMX à partir de la base de données (via le menu du clic droit) et de vérifier les mappages.