简体   繁体   English

实体框架未以1:0..1关系插入相关记录(意外结果)

[英]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. 自从我上一篇文章以来已经有一段时间了,这一次我需要一些帮助,以了解使用Code-First方法在c#中使用Entity Framework(SQL Server)进行的操作。

Let me show you the code i have: 让我告诉你我的代码:

Blog.cs 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 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 RegularAuthor.cs

using System;

namespace Helper.Models
{
    public class RegularAuthor : Author
    {
        public DateTime DateOfFirstBlogPost { get; set; }
    }
}

GuestAuthor.cs GuestAuthor.cs

namespace Helper.Models
{
    public class GuestAuthor : Author
    {
        public string OriginalBlogAccess { get; set; }
    }
}

DefaultDB.cs 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 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. 运行代码后,我还提供了SQL快照和结果。

SQL快照和数据库中的结果数据

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. author类应该具有博客列表,因此,当您添加Author实体时,可以根据需要添加任意数量的Blog。

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

In the Blog class you can change the following: 在Blog类中,您可以更改以下内容:

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 由于博客由author对象中的Blog属性引用,因此它们将被添加到数据库中

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: 同时Blog类:

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: 运行代码后:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM