Can anyone write mini-guide which explains how to work with collections in EF?
For example I have following models:
public class BlogPost
{
publ
It seems that Comments
navigation property does not works properly. Try to provide to BlogPost
model the actual referencig field to PostComment
table. Also rename the navigation property in PostComments for the EF naming compliance.
public class BlogPost
{
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public DateTime DateTime { get; set; }
public int PosCommentId {get; set; }
public List<PostComment> PostComments { get; set; }
}
If this neither works you have to define manually your relationship, but before help in this, you'd better provide the schema of this two tables in your db.
UPDATE 01:
First tip:
You are using singular named tables. This is not compliant to EF naming convention. Pluralization has to be turned off. Just put this line in OnModelCreating
method.
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
Second tip: My previous advice was totally wrong do not consider it anymore, just use your old models schema. Now, assuming a one-to-many relationship between comment and post:
protected override void OnModelCreating(ModelBuilder builder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<PostComment>().HasRequired<BlogPost>(c => c.ParentPost)
.WithMany(p => p.Comments);
base.OnModelCreating(builder);
}
For more INFOs :
EF one-to-many relationship tutorial
Relationship and navigation properties
Configuring Relationships with the Fluent API
Just to add on answers from @FabioCarello and @bricela, I recommend using the virtual keyword on Navigation Properties:
public virtual ICollection<Comment> { get; set; }
This will allow Lazy Loading, which means that the collections/references will be loaded only upon first call and not during first data retrieve. That is very useful to avoid, for example, stack overflows on recursive references.
No Fluent is necessary for simple one-to-many relationships like yours, unless you need non-standard behaviors like explicitly requiring non-nullable references.
You can also make explicit uses of foreign keys which is useful so you don't have to load the parent when you only need its Id:
public class PostComment
{
public int Id { get; set; }
public BlogPost ParentPost { get; set; }
// //
public int? ParentPostId { get; set; }
// //
public string Content { get; set; }
public DateTime DateTime { get; set; }
}
Here are my tips for working with navigation properties in Entity Framework Core.
Tip 1: Initialize collections
class Post
{
public int Id { get; set; }
// Initialize to prevent NullReferenceException
public ICollection<Comment> Comments { get; } = new List<Comment>();
}
class Comment
{
public int Id { get; set; }
public string User { get; set; }
public int PostId { get; set; }
public Post Post { get; set; }
}
Tip 2: Build using the HasOne
and WithMany
or HasMany
and WithOne
methods
protected override void OnModelCreating(ModelBuilder model)
{
model.Entity<Post>()
.HasMany(p => p.Comments).WithOne(c => c.Post)
.HasForeignKey(c => c.PostId);
}
Tip 3: Eagerly load the collection
var posts = db.Posts.Include(p => p.Comments);
Tip 4: Explicitly load if you didn't eagerly
db.Comments.Where(c => c.PostId == post.Id).Load();