Entity Framework not inserting a related record in a 1:0..1 relationship (Unexpected result)
it's been a while since my last post, this time i need some help to understand something that is goin on with Entity Framework (SQL Server) in c# using Code-First aproach.
Let me show you the code i have:
Blog.cs
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Helper.Models
{
public class Blog
{
[Key]
public int BlogId { get; set; }
public string BlogTitle { get; set; }
public virtual ICollection<Post> Posts { get; set; }
public virtual Author Author { get; set; }
}
}
Author.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Helper.Models
{
public class Author
{
[Key,ForeignKey("Blog")]
public int AuthorId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public virtual Blog Blog { get; set; }
}
}
RegularAuthor.cs
using System;
namespace Helper.Models
{
public class RegularAuthor : Author
{
public DateTime DateOfFirstBlogPost { get; set; }
}
}
GuestAuthor.cs
namespace Helper.Models
{
public class GuestAuthor : Author
{
public string OriginalBlogAccess { get; set; }
}
}
DefaultDB.cs
using Helper.Models;
using System.Data.Entity;
namespace EF_Basics
{
public class DefaultDB : DbContext
{
public DefaultDB(): base("EFDemo")
{
}
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<Author> Authors { get; set; }
}
}
Program.cs
using Helper.Models;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace EF_Basics
{
class Testing
{
static void Main(string args)
{
TestInsert2();
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
private static void TestInsert2()
{
using (DefaultDB ctx = new DefaultDB())
{
RegularAuthor author1 = new RegularAuthor()
{
Name = "First Author",
Address = GetLocalIpAddress(),
DateOfFirstBlogPost = DateTime.Now
};
GuestAuthor guest1 = new GuestAuthor()
{
Name = "Second Author",
Address = GetLocalIpAddress(),
OriginalBlogAccess = "Never"
};
List<Blog> BlogList = new List<Blog>()
{
new Blog
{
Author = author1,
BlogTitle = "Mid Century Modern DIY Dog House Build"
},
new Blog
{
Author = guest1,
BlogTitle = "Elf Doughnut Box Printable"
},
new Blog
{
Author = author1,
BlogTitle = "5 Ways to Make Giant Candy for a Candyland Theme"
}
};
foreach (var blog in BlogList)
{
Console.WriteLine($"Adding '{blog.BlogTitle}' by '{blog.Author.Name}'");
ctx.Blogs.Add(blog);
Thread.Sleep(1000);
Console.WriteLine();
}
ctx.SaveChanges();
}
}
private static string GetLocalIpAddress()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
throw new Exception("No network adapters with an IPv4 address in the system!");
}
}
}
So... now that we have all the pertinent code, when i run it all get "most" of the info into the database, but the last record just ignores all of the author data. I also included a snapshot of the SQL and the result after running the code.
c# sql-server entity-framework
add a comment |
it's been a while since my last post, this time i need some help to understand something that is goin on with Entity Framework (SQL Server) in c# using Code-First aproach.
Let me show you the code i have:
Blog.cs
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Helper.Models
{
public class Blog
{
[Key]
public int BlogId { get; set; }
public string BlogTitle { get; set; }
public virtual ICollection<Post> Posts { get; set; }
public virtual Author Author { get; set; }
}
}
Author.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Helper.Models
{
public class Author
{
[Key,ForeignKey("Blog")]
public int AuthorId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public virtual Blog Blog { get; set; }
}
}
RegularAuthor.cs
using System;
namespace Helper.Models
{
public class RegularAuthor : Author
{
public DateTime DateOfFirstBlogPost { get; set; }
}
}
GuestAuthor.cs
namespace Helper.Models
{
public class GuestAuthor : Author
{
public string OriginalBlogAccess { get; set; }
}
}
DefaultDB.cs
using Helper.Models;
using System.Data.Entity;
namespace EF_Basics
{
public class DefaultDB : DbContext
{
public DefaultDB(): base("EFDemo")
{
}
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<Author> Authors { get; set; }
}
}
Program.cs
using Helper.Models;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace EF_Basics
{
class Testing
{
static void Main(string args)
{
TestInsert2();
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
private static void TestInsert2()
{
using (DefaultDB ctx = new DefaultDB())
{
RegularAuthor author1 = new RegularAuthor()
{
Name = "First Author",
Address = GetLocalIpAddress(),
DateOfFirstBlogPost = DateTime.Now
};
GuestAuthor guest1 = new GuestAuthor()
{
Name = "Second Author",
Address = GetLocalIpAddress(),
OriginalBlogAccess = "Never"
};
List<Blog> BlogList = new List<Blog>()
{
new Blog
{
Author = author1,
BlogTitle = "Mid Century Modern DIY Dog House Build"
},
new Blog
{
Author = guest1,
BlogTitle = "Elf Doughnut Box Printable"
},
new Blog
{
Author = author1,
BlogTitle = "5 Ways to Make Giant Candy for a Candyland Theme"
}
};
foreach (var blog in BlogList)
{
Console.WriteLine($"Adding '{blog.BlogTitle}' by '{blog.Author.Name}'");
ctx.Blogs.Add(blog);
Thread.Sleep(1000);
Console.WriteLine();
}
ctx.SaveChanges();
}
}
private static string GetLocalIpAddress()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
throw new Exception("No network adapters with an IPv4 address in the system!");
}
}
}
So... now that we have all the pertinent code, when i run it all get "most" of the info into the database, but the last record just ignores all of the author data. I also included a snapshot of the SQL and the result after running the code.
c# sql-server entity-framework
it's not a null record, it's just a Blog not linked to an Author. You have no "null author" inserted in your db. You see nulls because of the left join. What does aselect b.* from Blog b
show ?
– Pac0
Nov 23 '18 at 17:19
When I do a separate select for each table I can see 3 entries at the blogs table and only 2 at the authors table... i know it is a 1:1 relationship between both tables but from the code side I am reusing the first author, so it should just work, since it’s a new blog.
– AcidRod75
Nov 23 '18 at 17:26
You’re attempting to link an author to two different blogs when it’s a 1:? relationship. The author can only reference a single blog so one of the two blogs will not have a related author
– Moho
Nov 23 '18 at 19:56
add a comment |
it's been a while since my last post, this time i need some help to understand something that is goin on with Entity Framework (SQL Server) in c# using Code-First aproach.
Let me show you the code i have:
Blog.cs
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Helper.Models
{
public class Blog
{
[Key]
public int BlogId { get; set; }
public string BlogTitle { get; set; }
public virtual ICollection<Post> Posts { get; set; }
public virtual Author Author { get; set; }
}
}
Author.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Helper.Models
{
public class Author
{
[Key,ForeignKey("Blog")]
public int AuthorId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public virtual Blog Blog { get; set; }
}
}
RegularAuthor.cs
using System;
namespace Helper.Models
{
public class RegularAuthor : Author
{
public DateTime DateOfFirstBlogPost { get; set; }
}
}
GuestAuthor.cs
namespace Helper.Models
{
public class GuestAuthor : Author
{
public string OriginalBlogAccess { get; set; }
}
}
DefaultDB.cs
using Helper.Models;
using System.Data.Entity;
namespace EF_Basics
{
public class DefaultDB : DbContext
{
public DefaultDB(): base("EFDemo")
{
}
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<Author> Authors { get; set; }
}
}
Program.cs
using Helper.Models;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace EF_Basics
{
class Testing
{
static void Main(string args)
{
TestInsert2();
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
private static void TestInsert2()
{
using (DefaultDB ctx = new DefaultDB())
{
RegularAuthor author1 = new RegularAuthor()
{
Name = "First Author",
Address = GetLocalIpAddress(),
DateOfFirstBlogPost = DateTime.Now
};
GuestAuthor guest1 = new GuestAuthor()
{
Name = "Second Author",
Address = GetLocalIpAddress(),
OriginalBlogAccess = "Never"
};
List<Blog> BlogList = new List<Blog>()
{
new Blog
{
Author = author1,
BlogTitle = "Mid Century Modern DIY Dog House Build"
},
new Blog
{
Author = guest1,
BlogTitle = "Elf Doughnut Box Printable"
},
new Blog
{
Author = author1,
BlogTitle = "5 Ways to Make Giant Candy for a Candyland Theme"
}
};
foreach (var blog in BlogList)
{
Console.WriteLine($"Adding '{blog.BlogTitle}' by '{blog.Author.Name}'");
ctx.Blogs.Add(blog);
Thread.Sleep(1000);
Console.WriteLine();
}
ctx.SaveChanges();
}
}
private static string GetLocalIpAddress()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
throw new Exception("No network adapters with an IPv4 address in the system!");
}
}
}
So... now that we have all the pertinent code, when i run it all get "most" of the info into the database, but the last record just ignores all of the author data. I also included a snapshot of the SQL and the result after running the code.
c# sql-server entity-framework
it's been a while since my last post, this time i need some help to understand something that is goin on with Entity Framework (SQL Server) in c# using Code-First aproach.
Let me show you the code i have:
Blog.cs
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Helper.Models
{
public class Blog
{
[Key]
public int BlogId { get; set; }
public string BlogTitle { get; set; }
public virtual ICollection<Post> Posts { get; set; }
public virtual Author Author { get; set; }
}
}
Author.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Helper.Models
{
public class Author
{
[Key,ForeignKey("Blog")]
public int AuthorId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public virtual Blog Blog { get; set; }
}
}
RegularAuthor.cs
using System;
namespace Helper.Models
{
public class RegularAuthor : Author
{
public DateTime DateOfFirstBlogPost { get; set; }
}
}
GuestAuthor.cs
namespace Helper.Models
{
public class GuestAuthor : Author
{
public string OriginalBlogAccess { get; set; }
}
}
DefaultDB.cs
using Helper.Models;
using System.Data.Entity;
namespace EF_Basics
{
public class DefaultDB : DbContext
{
public DefaultDB(): base("EFDemo")
{
}
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<Author> Authors { get; set; }
}
}
Program.cs
using Helper.Models;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace EF_Basics
{
class Testing
{
static void Main(string args)
{
TestInsert2();
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
private static void TestInsert2()
{
using (DefaultDB ctx = new DefaultDB())
{
RegularAuthor author1 = new RegularAuthor()
{
Name = "First Author",
Address = GetLocalIpAddress(),
DateOfFirstBlogPost = DateTime.Now
};
GuestAuthor guest1 = new GuestAuthor()
{
Name = "Second Author",
Address = GetLocalIpAddress(),
OriginalBlogAccess = "Never"
};
List<Blog> BlogList = new List<Blog>()
{
new Blog
{
Author = author1,
BlogTitle = "Mid Century Modern DIY Dog House Build"
},
new Blog
{
Author = guest1,
BlogTitle = "Elf Doughnut Box Printable"
},
new Blog
{
Author = author1,
BlogTitle = "5 Ways to Make Giant Candy for a Candyland Theme"
}
};
foreach (var blog in BlogList)
{
Console.WriteLine($"Adding '{blog.BlogTitle}' by '{blog.Author.Name}'");
ctx.Blogs.Add(blog);
Thread.Sleep(1000);
Console.WriteLine();
}
ctx.SaveChanges();
}
}
private static string GetLocalIpAddress()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
throw new Exception("No network adapters with an IPv4 address in the system!");
}
}
}
So... now that we have all the pertinent code, when i run it all get "most" of the info into the database, but the last record just ignores all of the author data. I also included a snapshot of the SQL and the result after running the code.
c# sql-server entity-framework
c# sql-server entity-framework
edited Nov 23 '18 at 19:12
AcidRod75
asked Nov 23 '18 at 17:07
AcidRod75AcidRod75
206
206
it's not a null record, it's just a Blog not linked to an Author. You have no "null author" inserted in your db. You see nulls because of the left join. What does aselect b.* from Blog b
show ?
– Pac0
Nov 23 '18 at 17:19
When I do a separate select for each table I can see 3 entries at the blogs table and only 2 at the authors table... i know it is a 1:1 relationship between both tables but from the code side I am reusing the first author, so it should just work, since it’s a new blog.
– AcidRod75
Nov 23 '18 at 17:26
You’re attempting to link an author to two different blogs when it’s a 1:? relationship. The author can only reference a single blog so one of the two blogs will not have a related author
– Moho
Nov 23 '18 at 19:56
add a comment |
it's not a null record, it's just a Blog not linked to an Author. You have no "null author" inserted in your db. You see nulls because of the left join. What does aselect b.* from Blog b
show ?
– Pac0
Nov 23 '18 at 17:19
When I do a separate select for each table I can see 3 entries at the blogs table and only 2 at the authors table... i know it is a 1:1 relationship between both tables but from the code side I am reusing the first author, so it should just work, since it’s a new blog.
– AcidRod75
Nov 23 '18 at 17:26
You’re attempting to link an author to two different blogs when it’s a 1:? relationship. The author can only reference a single blog so one of the two blogs will not have a related author
– Moho
Nov 23 '18 at 19:56
it's not a null record, it's just a Blog not linked to an Author. You have no "null author" inserted in your db. You see nulls because of the left join. What does a
select b.* from Blog b
show ?– Pac0
Nov 23 '18 at 17:19
it's not a null record, it's just a Blog not linked to an Author. You have no "null author" inserted in your db. You see nulls because of the left join. What does a
select b.* from Blog b
show ?– Pac0
Nov 23 '18 at 17:19
When I do a separate select for each table I can see 3 entries at the blogs table and only 2 at the authors table... i know it is a 1:1 relationship between both tables but from the code side I am reusing the first author, so it should just work, since it’s a new blog.
– AcidRod75
Nov 23 '18 at 17:26
When I do a separate select for each table I can see 3 entries at the blogs table and only 2 at the authors table... i know it is a 1:1 relationship between both tables but from the code side I am reusing the first author, so it should just work, since it’s a new blog.
– AcidRod75
Nov 23 '18 at 17:26
You’re attempting to link an author to two different blogs when it’s a 1:? relationship. The author can only reference a single blog so one of the two blogs will not have a related author
– Moho
Nov 23 '18 at 19:56
You’re attempting to link an author to two different blogs when it’s a 1:? relationship. The author can only reference a single blog so one of the two blogs will not have a related author
– Moho
Nov 23 '18 at 19:56
add a comment |
1 Answer
1
active
oldest
votes
I think the problem is that you are adding the blog to the database. Instead you should add the authors with their list of blogs.
The author class should have a list of blogs, so when you add an Author entity you can add as many Blogs as you require.
public List<Blog> Blogs { get; set; }
In the Blog class you can change the following:
public Author Author { get; set; }
This is an example of what should be done:
private static void TestInsert2()
{
using (DefaultDB ctx = new DefaultDB())
{
RegularAuthor author1 = new RegularAuthor()
{
Name = "First Author",
Address = GetLocalIpAddress(),
DateOfFirstBlogPost = DateTime.Now
};
GuestAuthor guest1 = new GuestAuthor()
{
Name = "Second Author",
Address = GetLocalIpAddress(),
OriginalBlogAccess = "Never"
};
author1.Blogs = new List<Blog>
{
new Blog
{
Author = author1,
BlogTitle = "Mid Century Modern DIY Dog House Build"
},
new Blog
{
Author = author1,
BlogTitle = "5 Ways to Make Giant Candy for a Candyland Theme"
}
}
guest1.Blogs = new List<Blog>
{
new Blog
{
Author = guest1,
BlogTitle = "Elf Doughnut Box Printable"
}
}
context.Add(author1);
context.Add(guest1);
ctx.SaveChanges();
}
}
As the blogs are referenced by the Blog property in the author object they will be added to the database
Edit:
This has taken some effort, but I think I have the solution. The table relationship is not correct.
What you are trying to do is to have an author with many blogs. Now that implies that the author object must have a collection of blogs.
The relationship you must have is the following:
In this scenario Blog has a foreign key to Author and as suggested in my main answer the Author class must have a collection of Blogs:
public partial class Author
{
public Author()
{
Blogs = new HashSet<Blog>();
}
public int authorId { get; set; }
public string name { get; set; }
public virtual ICollection<Blog> Blogs { get; set; }
}
Meanwhile the Blog class:
public partial class Blog
{
public int blogId { get; set; }
public string blogTitle { get; set; }
public int? authorId { get; set; }
public virtual Author Author { get; set; }
}
Your model will be:
public Model1()
{
}
public virtual DbSet<Author> Authors { get; set; }
public virtual DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Author>()
.Property(e => e.name)
.IsUnicode(false);
modelBuilder.Entity<Blog>()
.Property(e => e.blogTitle)
.IsUnicode(false);
}
Before running the code:
After running the code:
Okay, i see what you mean, will try it and see if there is any difference, but it is not very "logical" since i can add the author to a blog during the foreach loop.
– AcidRod75
Nov 23 '18 at 19:15
Your code as it is throws a nasty error (cannot explicity convert from Blog to List<Blog> or something like that), any way, i'm trying to understand why i can't loop thru a list of objects (as it is) and "reuse" one of those objects to insert a new record in the database.
– AcidRod75
Nov 23 '18 at 19:49
Did you change the Blog class with public List<Blog> Blogs { get; set; } ? The author entity is the one with a foreign key meaning it is the entity that must hold a reference to the blog entity. Not the other way around.
– Alex Leo
Nov 23 '18 at 20:03
Okay, so it looks like i can´t reuse any object in order to do an insert since Entity Framework is very "sctrict" in terms of object usage... what i think is happening here is that every time you create an object C# adds a "serial" to it and entity framework reads this serial and since what i'm working on is a 1:1 relatioship it will mark it as used, so even tho i CAN do a loop for every blog and say "i want this author for that blog" i will not do the insert for the last record since Entity Framework will ran out of new authors objects to keep doing a 1:1 insert. Pls correct me if i'm wrong
– AcidRod75
Nov 26 '18 at 12:54
Alex Leo that you A TON for that huge thing you posted there, but in reality what i intend to do is exactly have 1 author and 1 post, it is not a requirement, it is just me trying to not screw up a real project i'm working on doin some experimentation with some other "testing" console app so i can have more control. I hate the "fire and forget" thing, i want to know EXACTLY what is goin on behind the scene.
– AcidRod75
Nov 26 '18 at 13:07
|
show 1 more comment
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53450613%2fentity-framework-not-inserting-a-related-record-in-a-10-1-relationship-unexpe%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I think the problem is that you are adding the blog to the database. Instead you should add the authors with their list of blogs.
The author class should have a list of blogs, so when you add an Author entity you can add as many Blogs as you require.
public List<Blog> Blogs { get; set; }
In the Blog class you can change the following:
public Author Author { get; set; }
This is an example of what should be done:
private static void TestInsert2()
{
using (DefaultDB ctx = new DefaultDB())
{
RegularAuthor author1 = new RegularAuthor()
{
Name = "First Author",
Address = GetLocalIpAddress(),
DateOfFirstBlogPost = DateTime.Now
};
GuestAuthor guest1 = new GuestAuthor()
{
Name = "Second Author",
Address = GetLocalIpAddress(),
OriginalBlogAccess = "Never"
};
author1.Blogs = new List<Blog>
{
new Blog
{
Author = author1,
BlogTitle = "Mid Century Modern DIY Dog House Build"
},
new Blog
{
Author = author1,
BlogTitle = "5 Ways to Make Giant Candy for a Candyland Theme"
}
}
guest1.Blogs = new List<Blog>
{
new Blog
{
Author = guest1,
BlogTitle = "Elf Doughnut Box Printable"
}
}
context.Add(author1);
context.Add(guest1);
ctx.SaveChanges();
}
}
As the blogs are referenced by the Blog property in the author object they will be added to the database
Edit:
This has taken some effort, but I think I have the solution. The table relationship is not correct.
What you are trying to do is to have an author with many blogs. Now that implies that the author object must have a collection of blogs.
The relationship you must have is the following:
In this scenario Blog has a foreign key to Author and as suggested in my main answer the Author class must have a collection of Blogs:
public partial class Author
{
public Author()
{
Blogs = new HashSet<Blog>();
}
public int authorId { get; set; }
public string name { get; set; }
public virtual ICollection<Blog> Blogs { get; set; }
}
Meanwhile the Blog class:
public partial class Blog
{
public int blogId { get; set; }
public string blogTitle { get; set; }
public int? authorId { get; set; }
public virtual Author Author { get; set; }
}
Your model will be:
public Model1()
{
}
public virtual DbSet<Author> Authors { get; set; }
public virtual DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Author>()
.Property(e => e.name)
.IsUnicode(false);
modelBuilder.Entity<Blog>()
.Property(e => e.blogTitle)
.IsUnicode(false);
}
Before running the code:
After running the code:
Okay, i see what you mean, will try it and see if there is any difference, but it is not very "logical" since i can add the author to a blog during the foreach loop.
– AcidRod75
Nov 23 '18 at 19:15
Your code as it is throws a nasty error (cannot explicity convert from Blog to List<Blog> or something like that), any way, i'm trying to understand why i can't loop thru a list of objects (as it is) and "reuse" one of those objects to insert a new record in the database.
– AcidRod75
Nov 23 '18 at 19:49
Did you change the Blog class with public List<Blog> Blogs { get; set; } ? The author entity is the one with a foreign key meaning it is the entity that must hold a reference to the blog entity. Not the other way around.
– Alex Leo
Nov 23 '18 at 20:03
Okay, so it looks like i can´t reuse any object in order to do an insert since Entity Framework is very "sctrict" in terms of object usage... what i think is happening here is that every time you create an object C# adds a "serial" to it and entity framework reads this serial and since what i'm working on is a 1:1 relatioship it will mark it as used, so even tho i CAN do a loop for every blog and say "i want this author for that blog" i will not do the insert for the last record since Entity Framework will ran out of new authors objects to keep doing a 1:1 insert. Pls correct me if i'm wrong
– AcidRod75
Nov 26 '18 at 12:54
Alex Leo that you A TON for that huge thing you posted there, but in reality what i intend to do is exactly have 1 author and 1 post, it is not a requirement, it is just me trying to not screw up a real project i'm working on doin some experimentation with some other "testing" console app so i can have more control. I hate the "fire and forget" thing, i want to know EXACTLY what is goin on behind the scene.
– AcidRod75
Nov 26 '18 at 13:07
|
show 1 more comment
I think the problem is that you are adding the blog to the database. Instead you should add the authors with their list of blogs.
The author class should have a list of blogs, so when you add an Author entity you can add as many Blogs as you require.
public List<Blog> Blogs { get; set; }
In the Blog class you can change the following:
public Author Author { get; set; }
This is an example of what should be done:
private static void TestInsert2()
{
using (DefaultDB ctx = new DefaultDB())
{
RegularAuthor author1 = new RegularAuthor()
{
Name = "First Author",
Address = GetLocalIpAddress(),
DateOfFirstBlogPost = DateTime.Now
};
GuestAuthor guest1 = new GuestAuthor()
{
Name = "Second Author",
Address = GetLocalIpAddress(),
OriginalBlogAccess = "Never"
};
author1.Blogs = new List<Blog>
{
new Blog
{
Author = author1,
BlogTitle = "Mid Century Modern DIY Dog House Build"
},
new Blog
{
Author = author1,
BlogTitle = "5 Ways to Make Giant Candy for a Candyland Theme"
}
}
guest1.Blogs = new List<Blog>
{
new Blog
{
Author = guest1,
BlogTitle = "Elf Doughnut Box Printable"
}
}
context.Add(author1);
context.Add(guest1);
ctx.SaveChanges();
}
}
As the blogs are referenced by the Blog property in the author object they will be added to the database
Edit:
This has taken some effort, but I think I have the solution. The table relationship is not correct.
What you are trying to do is to have an author with many blogs. Now that implies that the author object must have a collection of blogs.
The relationship you must have is the following:
In this scenario Blog has a foreign key to Author and as suggested in my main answer the Author class must have a collection of Blogs:
public partial class Author
{
public Author()
{
Blogs = new HashSet<Blog>();
}
public int authorId { get; set; }
public string name { get; set; }
public virtual ICollection<Blog> Blogs { get; set; }
}
Meanwhile the Blog class:
public partial class Blog
{
public int blogId { get; set; }
public string blogTitle { get; set; }
public int? authorId { get; set; }
public virtual Author Author { get; set; }
}
Your model will be:
public Model1()
{
}
public virtual DbSet<Author> Authors { get; set; }
public virtual DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Author>()
.Property(e => e.name)
.IsUnicode(false);
modelBuilder.Entity<Blog>()
.Property(e => e.blogTitle)
.IsUnicode(false);
}
Before running the code:
After running the code:
Okay, i see what you mean, will try it and see if there is any difference, but it is not very "logical" since i can add the author to a blog during the foreach loop.
– AcidRod75
Nov 23 '18 at 19:15
Your code as it is throws a nasty error (cannot explicity convert from Blog to List<Blog> or something like that), any way, i'm trying to understand why i can't loop thru a list of objects (as it is) and "reuse" one of those objects to insert a new record in the database.
– AcidRod75
Nov 23 '18 at 19:49
Did you change the Blog class with public List<Blog> Blogs { get; set; } ? The author entity is the one with a foreign key meaning it is the entity that must hold a reference to the blog entity. Not the other way around.
– Alex Leo
Nov 23 '18 at 20:03
Okay, so it looks like i can´t reuse any object in order to do an insert since Entity Framework is very "sctrict" in terms of object usage... what i think is happening here is that every time you create an object C# adds a "serial" to it and entity framework reads this serial and since what i'm working on is a 1:1 relatioship it will mark it as used, so even tho i CAN do a loop for every blog and say "i want this author for that blog" i will not do the insert for the last record since Entity Framework will ran out of new authors objects to keep doing a 1:1 insert. Pls correct me if i'm wrong
– AcidRod75
Nov 26 '18 at 12:54
Alex Leo that you A TON for that huge thing you posted there, but in reality what i intend to do is exactly have 1 author and 1 post, it is not a requirement, it is just me trying to not screw up a real project i'm working on doin some experimentation with some other "testing" console app so i can have more control. I hate the "fire and forget" thing, i want to know EXACTLY what is goin on behind the scene.
– AcidRod75
Nov 26 '18 at 13:07
|
show 1 more comment
I think the problem is that you are adding the blog to the database. Instead you should add the authors with their list of blogs.
The author class should have a list of blogs, so when you add an Author entity you can add as many Blogs as you require.
public List<Blog> Blogs { get; set; }
In the Blog class you can change the following:
public Author Author { get; set; }
This is an example of what should be done:
private static void TestInsert2()
{
using (DefaultDB ctx = new DefaultDB())
{
RegularAuthor author1 = new RegularAuthor()
{
Name = "First Author",
Address = GetLocalIpAddress(),
DateOfFirstBlogPost = DateTime.Now
};
GuestAuthor guest1 = new GuestAuthor()
{
Name = "Second Author",
Address = GetLocalIpAddress(),
OriginalBlogAccess = "Never"
};
author1.Blogs = new List<Blog>
{
new Blog
{
Author = author1,
BlogTitle = "Mid Century Modern DIY Dog House Build"
},
new Blog
{
Author = author1,
BlogTitle = "5 Ways to Make Giant Candy for a Candyland Theme"
}
}
guest1.Blogs = new List<Blog>
{
new Blog
{
Author = guest1,
BlogTitle = "Elf Doughnut Box Printable"
}
}
context.Add(author1);
context.Add(guest1);
ctx.SaveChanges();
}
}
As the blogs are referenced by the Blog property in the author object they will be added to the database
Edit:
This has taken some effort, but I think I have the solution. The table relationship is not correct.
What you are trying to do is to have an author with many blogs. Now that implies that the author object must have a collection of blogs.
The relationship you must have is the following:
In this scenario Blog has a foreign key to Author and as suggested in my main answer the Author class must have a collection of Blogs:
public partial class Author
{
public Author()
{
Blogs = new HashSet<Blog>();
}
public int authorId { get; set; }
public string name { get; set; }
public virtual ICollection<Blog> Blogs { get; set; }
}
Meanwhile the Blog class:
public partial class Blog
{
public int blogId { get; set; }
public string blogTitle { get; set; }
public int? authorId { get; set; }
public virtual Author Author { get; set; }
}
Your model will be:
public Model1()
{
}
public virtual DbSet<Author> Authors { get; set; }
public virtual DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Author>()
.Property(e => e.name)
.IsUnicode(false);
modelBuilder.Entity<Blog>()
.Property(e => e.blogTitle)
.IsUnicode(false);
}
Before running the code:
After running the code:
I think the problem is that you are adding the blog to the database. Instead you should add the authors with their list of blogs.
The author class should have a list of blogs, so when you add an Author entity you can add as many Blogs as you require.
public List<Blog> Blogs { get; set; }
In the Blog class you can change the following:
public Author Author { get; set; }
This is an example of what should be done:
private static void TestInsert2()
{
using (DefaultDB ctx = new DefaultDB())
{
RegularAuthor author1 = new RegularAuthor()
{
Name = "First Author",
Address = GetLocalIpAddress(),
DateOfFirstBlogPost = DateTime.Now
};
GuestAuthor guest1 = new GuestAuthor()
{
Name = "Second Author",
Address = GetLocalIpAddress(),
OriginalBlogAccess = "Never"
};
author1.Blogs = new List<Blog>
{
new Blog
{
Author = author1,
BlogTitle = "Mid Century Modern DIY Dog House Build"
},
new Blog
{
Author = author1,
BlogTitle = "5 Ways to Make Giant Candy for a Candyland Theme"
}
}
guest1.Blogs = new List<Blog>
{
new Blog
{
Author = guest1,
BlogTitle = "Elf Doughnut Box Printable"
}
}
context.Add(author1);
context.Add(guest1);
ctx.SaveChanges();
}
}
As the blogs are referenced by the Blog property in the author object they will be added to the database
Edit:
This has taken some effort, but I think I have the solution. The table relationship is not correct.
What you are trying to do is to have an author with many blogs. Now that implies that the author object must have a collection of blogs.
The relationship you must have is the following:
In this scenario Blog has a foreign key to Author and as suggested in my main answer the Author class must have a collection of Blogs:
public partial class Author
{
public Author()
{
Blogs = new HashSet<Blog>();
}
public int authorId { get; set; }
public string name { get; set; }
public virtual ICollection<Blog> Blogs { get; set; }
}
Meanwhile the Blog class:
public partial class Blog
{
public int blogId { get; set; }
public string blogTitle { get; set; }
public int? authorId { get; set; }
public virtual Author Author { get; set; }
}
Your model will be:
public Model1()
{
}
public virtual DbSet<Author> Authors { get; set; }
public virtual DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Author>()
.Property(e => e.name)
.IsUnicode(false);
modelBuilder.Entity<Blog>()
.Property(e => e.blogTitle)
.IsUnicode(false);
}
Before running the code:
After running the code:
edited Nov 23 '18 at 23:00
answered Nov 23 '18 at 19:11
Alex LeoAlex Leo
516211
516211
Okay, i see what you mean, will try it and see if there is any difference, but it is not very "logical" since i can add the author to a blog during the foreach loop.
– AcidRod75
Nov 23 '18 at 19:15
Your code as it is throws a nasty error (cannot explicity convert from Blog to List<Blog> or something like that), any way, i'm trying to understand why i can't loop thru a list of objects (as it is) and "reuse" one of those objects to insert a new record in the database.
– AcidRod75
Nov 23 '18 at 19:49
Did you change the Blog class with public List<Blog> Blogs { get; set; } ? The author entity is the one with a foreign key meaning it is the entity that must hold a reference to the blog entity. Not the other way around.
– Alex Leo
Nov 23 '18 at 20:03
Okay, so it looks like i can´t reuse any object in order to do an insert since Entity Framework is very "sctrict" in terms of object usage... what i think is happening here is that every time you create an object C# adds a "serial" to it and entity framework reads this serial and since what i'm working on is a 1:1 relatioship it will mark it as used, so even tho i CAN do a loop for every blog and say "i want this author for that blog" i will not do the insert for the last record since Entity Framework will ran out of new authors objects to keep doing a 1:1 insert. Pls correct me if i'm wrong
– AcidRod75
Nov 26 '18 at 12:54
Alex Leo that you A TON for that huge thing you posted there, but in reality what i intend to do is exactly have 1 author and 1 post, it is not a requirement, it is just me trying to not screw up a real project i'm working on doin some experimentation with some other "testing" console app so i can have more control. I hate the "fire and forget" thing, i want to know EXACTLY what is goin on behind the scene.
– AcidRod75
Nov 26 '18 at 13:07
|
show 1 more comment
Okay, i see what you mean, will try it and see if there is any difference, but it is not very "logical" since i can add the author to a blog during the foreach loop.
– AcidRod75
Nov 23 '18 at 19:15
Your code as it is throws a nasty error (cannot explicity convert from Blog to List<Blog> or something like that), any way, i'm trying to understand why i can't loop thru a list of objects (as it is) and "reuse" one of those objects to insert a new record in the database.
– AcidRod75
Nov 23 '18 at 19:49
Did you change the Blog class with public List<Blog> Blogs { get; set; } ? The author entity is the one with a foreign key meaning it is the entity that must hold a reference to the blog entity. Not the other way around.
– Alex Leo
Nov 23 '18 at 20:03
Okay, so it looks like i can´t reuse any object in order to do an insert since Entity Framework is very "sctrict" in terms of object usage... what i think is happening here is that every time you create an object C# adds a "serial" to it and entity framework reads this serial and since what i'm working on is a 1:1 relatioship it will mark it as used, so even tho i CAN do a loop for every blog and say "i want this author for that blog" i will not do the insert for the last record since Entity Framework will ran out of new authors objects to keep doing a 1:1 insert. Pls correct me if i'm wrong
– AcidRod75
Nov 26 '18 at 12:54
Alex Leo that you A TON for that huge thing you posted there, but in reality what i intend to do is exactly have 1 author and 1 post, it is not a requirement, it is just me trying to not screw up a real project i'm working on doin some experimentation with some other "testing" console app so i can have more control. I hate the "fire and forget" thing, i want to know EXACTLY what is goin on behind the scene.
– AcidRod75
Nov 26 '18 at 13:07
Okay, i see what you mean, will try it and see if there is any difference, but it is not very "logical" since i can add the author to a blog during the foreach loop.
– AcidRod75
Nov 23 '18 at 19:15
Okay, i see what you mean, will try it and see if there is any difference, but it is not very "logical" since i can add the author to a blog during the foreach loop.
– AcidRod75
Nov 23 '18 at 19:15
Your code as it is throws a nasty error (cannot explicity convert from Blog to List<Blog> or something like that), any way, i'm trying to understand why i can't loop thru a list of objects (as it is) and "reuse" one of those objects to insert a new record in the database.
– AcidRod75
Nov 23 '18 at 19:49
Your code as it is throws a nasty error (cannot explicity convert from Blog to List<Blog> or something like that), any way, i'm trying to understand why i can't loop thru a list of objects (as it is) and "reuse" one of those objects to insert a new record in the database.
– AcidRod75
Nov 23 '18 at 19:49
Did you change the Blog class with public List<Blog> Blogs { get; set; } ? The author entity is the one with a foreign key meaning it is the entity that must hold a reference to the blog entity. Not the other way around.
– Alex Leo
Nov 23 '18 at 20:03
Did you change the Blog class with public List<Blog> Blogs { get; set; } ? The author entity is the one with a foreign key meaning it is the entity that must hold a reference to the blog entity. Not the other way around.
– Alex Leo
Nov 23 '18 at 20:03
Okay, so it looks like i can´t reuse any object in order to do an insert since Entity Framework is very "sctrict" in terms of object usage... what i think is happening here is that every time you create an object C# adds a "serial" to it and entity framework reads this serial and since what i'm working on is a 1:1 relatioship it will mark it as used, so even tho i CAN do a loop for every blog and say "i want this author for that blog" i will not do the insert for the last record since Entity Framework will ran out of new authors objects to keep doing a 1:1 insert. Pls correct me if i'm wrong
– AcidRod75
Nov 26 '18 at 12:54
Okay, so it looks like i can´t reuse any object in order to do an insert since Entity Framework is very "sctrict" in terms of object usage... what i think is happening here is that every time you create an object C# adds a "serial" to it and entity framework reads this serial and since what i'm working on is a 1:1 relatioship it will mark it as used, so even tho i CAN do a loop for every blog and say "i want this author for that blog" i will not do the insert for the last record since Entity Framework will ran out of new authors objects to keep doing a 1:1 insert. Pls correct me if i'm wrong
– AcidRod75
Nov 26 '18 at 12:54
Alex Leo that you A TON for that huge thing you posted there, but in reality what i intend to do is exactly have 1 author and 1 post, it is not a requirement, it is just me trying to not screw up a real project i'm working on doin some experimentation with some other "testing" console app so i can have more control. I hate the "fire and forget" thing, i want to know EXACTLY what is goin on behind the scene.
– AcidRod75
Nov 26 '18 at 13:07
Alex Leo that you A TON for that huge thing you posted there, but in reality what i intend to do is exactly have 1 author and 1 post, it is not a requirement, it is just me trying to not screw up a real project i'm working on doin some experimentation with some other "testing" console app so i can have more control. I hate the "fire and forget" thing, i want to know EXACTLY what is goin on behind the scene.
– AcidRod75
Nov 26 '18 at 13:07
|
show 1 more comment
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53450613%2fentity-framework-not-inserting-a-related-record-in-a-10-1-relationship-unexpe%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
it's not a null record, it's just a Blog not linked to an Author. You have no "null author" inserted in your db. You see nulls because of the left join. What does a
select b.* from Blog b
show ?– Pac0
Nov 23 '18 at 17:19
When I do a separate select for each table I can see 3 entries at the blogs table and only 2 at the authors table... i know it is a 1:1 relationship between both tables but from the code side I am reusing the first author, so it should just work, since it’s a new blog.
– AcidRod75
Nov 23 '18 at 17:26
You’re attempting to link an author to two different blogs when it’s a 1:? relationship. The author can only reference a single blog so one of the two blogs will not have a related author
– Moho
Nov 23 '18 at 19:56