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

时间:2018-11-23 17:07:19

标签: c# sql-server entity-framework

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

让我告诉您我拥有的代码:

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!");
        }
    }
}

所以...现在我们有了所有相关的代码,当我运行它们时,所有这些信息都将“大部分”信息存入了数据库,但是最后一条记录只是忽略了所有作者数据。运行代码后,我还提供了SQL快照和结果。

Snapshot of the SQL and resulting data from the database

1 个答案:

答案 0 :(得分:0)

我认为问题在于您正在将博客添加到数据库中。相反,您应该添加作者及其博客列表。

author类应该具有博客列表,因此,当您添加Author实体时,您可以根据需要添加任意数量的Blog。

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

在Blog类中,您可以更改以下内容:

public Author Author { get; set; }

这是应该执行的操作的示例:

    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();
    }
   }

由于blog被author对象中的Blog属性引用,它们将被添加到数据库中

编辑:

这已经付出了一些努力,但是我想我有解决方案。表关系不正确。

您想要做的是让一个拥有许多博客的作者。现在,这意味着author对象必须具有博客集合。

您必须具有的关系如下:

enter image description here

在这种情况下,博客具有作者的外键,并且正如我主要回答中所建议的那样,作者类必须具有博客的集合:

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; }
}

同时使用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; }
}

您的模型将是:

   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);
    }

运行代码之前:

enter image description here

运行代码后:

enter image description here