Insert new/Update existing record with one to many relationship

18,838

Solution 1

try Adding

public Blog Blog { get; set; }

property to Post and configure

          modelBuilder.Entity<Post >().HasRequired(n => n.Blog)
            .WithMany(n=>n.Posts )
            .HasForeignKey(n => n.BlogId)
            .WillCascadeOnDelete(true);

in OnModelCreating(DbModelBuilder modelBuilder) in the context definition

Then regenerate Database

Solution 2

Should be something like:

Blog blog = context.Blogs.FirstOrDefault(b => b.Title == blogTitle);

// no blog with this title yet, create a new one
if (blog == null) {
    blog = new Blog();
    blog.Title = blogTitle;
    blog.Posts = new Collection<Post>();
    context.Blogs.Add(blog);
} 

Post p = new Post();
p.Title = postTitle;
p.Content = "some content";
blog.Posts.Add(p);

context.SaveChanges();

Furthermore I would delete Posts initialization in the constructor.

Share:
18,838
inside
Author by

inside

enter code here #SOreadytohelp

Updated on August 18, 2022

Comments

  • inside
    inside over 1 year

    I have two simple models from which I am creating database tables with the help of Entity Framework:

    public class Blog 
    { 
        public int Id { get; set; } 
        public string Title { get; set; } 
        public virtual ICollection<Post> Posts { get; set; } 
    
        public Blog() 
        {
            Posts = new Collection<Post>();
        }
    } 
    
    public class Post 
    { 
        public int Id { get; set; } 
        public string Title { get; set; } 
        public string Content { get; set; } 
        // foreign key of Blog table
        public int BlogId { get; set; } 
    }
    

    Now In my DB Context I have DBSet to generate database tables:

    public DbSet<Blog> Blogs { get; set; }
    

    Database tables are generated as expected, but now the question, how do I insert new Blog with posts to the DB. I've tried something like this:

    Blog blog = context.Blogs.FirstOrDefault(b => b.Title == blogTitle);
    
    // no blog with this title yet, create a new one
    if (blog == null) {
        blog = new Blog();
        blog.Title = blogTitle;
    
        Post p = new Post();
        p.Title = postTitle;
        p.Content = "some content";
    
        blog.Posts.Add(p);
        context.Blogs.Add(blog);
    } 
    // this blog already exist, just add post to it 
    else 
    {
        Post p = new Post();
        p.Title = postTitle;
        p.Content = "some content";
        context.Blogs.FirstOrDefault(b => b.Title == blogTitle).Posts.Add(p);
    }
    
    context.SaveChanges();
    

    As you can see I am not touching Id and BlogId, as those should be generated by EntityFramework automatically.

    However, using this code, only my Blog is getting inserted into database, next time I'll try to execute the same code it will tell me that the Posts collection of my blog is empty.

    Am I doing something wrong? Is there a better practice for doing insertion/update of records to the DB with one to many relationship?

    Thank you

    UPDATE:

    Thanks to answers, I was able to insert both Blog and Post into my DB, however, my post is still not linked to the particular Blog, BlogId inside Post table is always 0.

    Do I need to increment it manually or maybe some kind of attribute?