Entity Framework не вставляет связанную запись в отношении 1: 0..1 (неожиданный результат) - PullRequest
0 голосов
/ 23 ноября 2018

прошло много времени с момента моего последнего поста, на этот раз мне нужна помощь, чтобы понять кое-что, что происходит с Entity Framework (SQL Server) в c # с использованием подхода Code-First.

Позвольте мне показать вамкод, который у меня есть:

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 голосов
/ 23 ноября 2018

Мне кажется, проблема в том, что вы добавляете блог в базу данных.Вместо этого вы должны добавить авторов с их списком блогов.

В классе автора должен быть список блогов, поэтому при добавлении сущности Автор вы можете добавить столько блогов, сколько вам нужно.

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

В классе Блог вы можете изменить следующее:

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

Поскольку блоги ссылаются на блогсвойство в объекте автора они будут добавлены в базу данных

Редактировать:

Это потребовало некоторых усилий, но я думаю, что у меня есть решение.Неверное соотношение таблиц.

Вы пытаетесь сделать так, чтобы у автора было много блогов.Теперь это означает, что объект 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; }
}

. Между тем, класс блога:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...