I'm new to EF Core, and using this tutorial I've got an unexpected result, namely, the data looks normal in the model when it's just populated, but in a new instance of the context, the navigation property in the principal entity is not populated, and the navigation property in the dependent entity is populated in a peculiar way.
Here is the model (the code from the tutorial is slightly modified):
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
namespace EFGetStarted
{
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlite("Data Source=blogging.db");
}
}
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public List<Post> Posts { get; } = new List<Post>();
public override string ToString()
{
return
"{" +
"BlogId: " + BlogId + ", " +
"Name: " + Name + ", " +
"Posts.Count: " + Posts.Count +
"}";
}
}
public class Post
{
public int PostId { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
public override string ToString()
{
return
"{" +
"PostId: " + PostId + ", " +
"Content: " + Content + ", " +
"BlogId: " + BlogId +
"}";
}
}
}
And here is the program:
using static System.Console;
namespace EFGetStarted
{
class Program
{
static void Main()
{
CreateContents(new BloggingContext());
Print(new BloggingContext());
}
static void CreateContents(BloggingContext db)
{
AddBlog(db);
Print(db);
}
private static void AddBlog(BloggingContext db)
{
var blog = new Blog { Name = "Blog 1" };
db.Add(blog);
blog.Posts.Add(new Post { Content = "Post 1" });
blog.Posts.Add(new Post { Content = "Post 2" });
blog.Posts.Add(new Post { Content = "Post 3" });
db.SaveChanges();
}
private static void Print(BloggingContext db)
{
PrintBlogs(db);
PrintPosts(db);
}
private static void PrintBlogs(BloggingContext db)
{
WriteLine("---- Blogs: ----");
foreach (var blog in db.Blogs) Print(blog);
WriteLine("");
}
private static void PrintPosts(BloggingContext db)
{
WriteLine("---- Posts: ----");
foreach (var post in db.Posts) Print(post);
WriteLine("");
}
private static void Print(Blog blog)
{
WriteLine(blog);
foreach (var post in blog.Posts) WriteLine(post);
WriteLine();
}
private static void Print(Post post)
{
WriteLine(post);
WriteLine(post.Blog);
foreach (var blogPost in post.Blog.Posts) WriteLine(blogPost);
WriteLine();
}
}
}
The program produces the following output:
---- Blogs: ----
{BlogId: 1, Name: 'Blog 1', Posts.Count: 3}
{PostId: 1, Content: 'Post 1', BlogId: 1}
{PostId: 2, Content: 'Post 2', BlogId: 1}
{PostId: 3, Content: 'Post 3', BlogId: 1}
---- Posts: ----
{PostId: 1, Content: 'Post 1', BlogId: 1}
{BlogId: 1, Name: 'Blog 1', Posts.Count: 3}
{PostId: 1, Content: 'Post 1', BlogId: 1}
{PostId: 2, Content: 'Post 2', BlogId: 1}
{PostId: 3, Content: 'Post 3', BlogId: 1}
{PostId: 2, Content: 'Post 2', BlogId: 1}
{BlogId: 1, Name: 'Blog 1', Posts.Count: 3}
{PostId: 1, Content: 'Post 1', BlogId: 1}
{PostId: 2, Content: 'Post 2', BlogId: 1}
{PostId: 3, Content: 'Post 3', BlogId: 1}
{PostId: 3, Content: 'Post 3', BlogId: 1}
{BlogId: 1, Name: 'Blog 1', Posts.Count: 3}
{PostId: 1, Content: 'Post 1', BlogId: 1}
{PostId: 2, Content: 'Post 2', BlogId: 1}
{PostId: 3, Content: 'Post 3', BlogId: 1}
---- Blogs: ----
{BlogId: 1, Name: 'Blog 1', Posts.Count: 0}
---- Posts: ----
{PostId: 1, Content: 'Post 1', BlogId: 1}
{BlogId: 1, Name: 'Blog 1', Posts.Count: 1}
{PostId: 1, Content: 'Post 1', BlogId: 1}
{PostId: 2, Content: 'Post 2', BlogId: 1}
{BlogId: 1, Name: 'Blog 1', Posts.Count: 2}
{PostId: 1, Content: 'Post 1', BlogId: 1}
{PostId: 2, Content: 'Post 2', BlogId: 1}
{PostId: 3, Content: 'Post 3', BlogId: 1}
{BlogId: 1, Name: 'Blog 1', Posts.Count: 3}
{PostId: 1, Content: 'Post 1', BlogId: 1}
{PostId: 2, Content: 'Post 2', BlogId: 1}
{PostId: 3, Content: 'Post 3', BlogId: 1}
As you can see, when the model is created, the blog has three posts, and every post references the blog with the same three posts.
When printed using a new instance of the context, the blog has zero posts and, looks like, posts reference different instances of the blog each with a different number of associated posts.
How to make the model in the new instance of the context look like the one in which it was populated?
There is a bug in the code. Code doesn't have include statement, this is why you can't see posts. Try this:
private static void PrintBlogs(BloggingContext db)
{
var blogs = db.Blogs.Include(i => i.Posts).ToArray();
WriteLine("---- Blogs: ----");
foreach (var blog in blogs) Print(blog);
WriteLine("");
}
private static void PrintPosts(BloggingContext db)
{
var posts = db.Posts.Include(i => i.Blog).ToArray();
WriteLine("---- Posts: ----");
foreach (var post in posts) Print(post);
WriteLine("");
}
Now the result is:
---- Blogs: ----
{BlogId: 1, Name: Blog 1, Posts.Count: 3}
{PostId: 1, Content: Post 1, BlogId: 1}
{PostId: 2, Content: Post 2, BlogId: 1}
{PostId: 3, Content: Post 3, BlogId: 1}
---- Posts: ----
{PostId: 1, Content: Post 1, BlogId: 1}
{BlogId: 1, Name: Blog 1, Posts.Count: 3}
{PostId: 1, Content: Post 1, BlogId: 1}
{PostId: 2, Content: Post 2, BlogId: 1}
{PostId: 3, Content: Post 3, BlogId: 1}
{PostId: 2, Content: Post 2, BlogId: 1}
{BlogId: 1, Name: Blog 1, Posts.Count: 3}
{PostId: 1, Content: Post 1, BlogId: 1}
{PostId: 2, Content: Post 2, BlogId: 1}
{PostId: 3, Content: Post 3, BlogId: 1}
{PostId: 3, Content: Post 3, BlogId: 1}
{BlogId: 1, Name: Blog 1, Posts.Count: 3}
{PostId: 1, Content: Post 1, BlogId: 1}
{PostId: 2, Content: Post 2, BlogId: 1}
{PostId: 3, Content: Post 3, BlogId: 1}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.