繁体   English   中英

EF Core 将实体连接到视图。 一对多

[英]EF Core connect Entity to View. One to Many

我有一个简单的项目来显示问题,我想将ICollection<Post>与视图View_BlogPosts连接起来。 这只是简化的场景,在现实生活中,我需要将实体与大视图与来自不同表的许多列连接起来。

代码中最有趣的部分是: OnModelCreating(ModelBuilder modelBuilder)其中有配置 View with Entity: Post (一个博客到多个帖子)。 但它现在不起作用,这行代码: var test = db.BlogWithPosts.ToList(); 返回空的帖子集合。 在此处输入图像描述

如何解决这个问题?

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace Samples
{
    public class Program
    {
        private static void Main()
        {
            SetupDatabase();

            using (var db = new BloggingContext())
            {
                var test = db.BlogWithPosts.ToList();
            }
        }

        private static void SetupDatabase()
        {
            using (var db = new BloggingContext())
            {
                if (db.Database.EnsureCreated())
                {
                    db.Blogs.Add(
                        new Blog
                        {
                            Name = "Fish Blog",
                            Url = "http://sample.com/blogs/fish",
                            Posts = new List<Post>
                            {
                                new Post { Title = "Fish care 101" },
                                new Post { Title = "Caring for tropical fish" },
                                new Post { Title = "Types of ornamental fish" }
                            }
                        });

                    db.Blogs.Add(
                        new Blog
                        {
                            Name = "Cats Blog",
                            Url = "http://sample.com/blogs/cats",
                            Posts = new List<Post>
                            {
                                new Post { Title = "Cat care 101" },
                                new Post { Title = "Caring for tropical cats" },
                                new Post { Title = "Types of ornamental cats" }
                            }
                        });

                    db.Blogs.Add(
                        new Blog
                        {
                            Name = "Catfish Blog",
                            Url = "http://sample.com/blogs/catfish",
                            Posts = new List<Post>
                            {
                                new Post { Title = "Catfish care 101" }, new Post { Title = "History of the catfish name" }
                            }
                        });

                    db.SaveChanges();

                    db.Database.ExecuteSqlRaw(
                     @"CREATE VIEW View_BlogPosts AS
                            SELECT b.Name , b.BlogId, b.Url FROM Blogs b");
                }
            }
        }
    }

    public class BloggingContext : DbContext
    {
        private static readonly ILoggerFactory _loggerFactory
            = LoggerFactory.Create(
                builder => builder.AddConsole().AddFilter((c, l) => l == LogLevel.Information && !c.EndsWith("Connection")));

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

        public DbSet<BlogWithPosts> BlogWithPosts { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder
                .UseSqlServer(
                   // @"Server=(localdb)\mssqllocaldb;Database=Sample.KeylessEntityTypes;Trusted_Connection=True;ConnectRetryCount=0;")
                   @"Server=.\SQLEXPRESS;Database=test_view;Trusted_Connection=True;")
                .UseLoggerFactory(_loggerFactory);
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<BlogWithPosts>(eb =>
            {
                //eb.HasNoKey();
                eb.ToView("View_BlogPosts");
                eb.HasKey(bwp => bwp.BlogId);
                eb.Property(v => v.BlogName).HasColumnName("Name");

                eb
                .HasMany(bwp => bwp.Posts)
                .WithOne()
                .HasForeignKey(p => p.BlogId);
            });
        }
    }
   
    public class Blog
    {
        public int BlogId { get; set; }
        public string Name { get; set; }
        public string Url { get; set; }
        public ICollection<Post> Posts { get; set; }
    }

    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
        public int BlogId { get; set; }
    }

    public class BlogWithPosts
    {
        public int BlogId { get; set; }
        public string BlogName { get; set; }
        public ICollection<Post> Posts { get; set; } = new List<Post>();
    }
}

编辑:
感谢@Neil W 的回答:

这很好,但是在var test = db.BlogWithPosts.Include(bwp => bwp.Posts).ToList(); 仍然没有帖子。

我在运行程序后检查了数据库,在 Post 表中我发现,添加了第二个 ID: BlogId1 在此处输入图像描述

我已经填写了与BlogId1相同的BlogId列,如下所示: 在此处输入图像描述 并出现了帖子

但是如何设置第二个 id: BlogId1的配置不会出现。

您需要在访问上下文时询问相关实体,使用包括:

var test = db.BlogWithPosts.Include(bwp => bwp.Posts).ToList();

感谢所有的回答和评论。 正如@atiyar 所说, PostBlog之间应该有明确的关系,这会停止创建BlogId1列。 所以工作示例如下:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace Samples
{
    public class Program
    {
        private static void Main()
        {
            SetupDatabase();

            using (var db = new BloggingContext())
            {

                var test = db.BlogWithPosts.Include(bp => bp.Posts).ToList();
            }
        }

        private static void SetupDatabase()
        {
            using (var db = new BloggingContext())
            {
                if (db.Database.EnsureCreated())
                {
                    db.Blogs.Add(
                        new Blog
                        {
                            Name = "Fish Blog",
                            Url = "http://sample.com/blogs/fish",
                            Posts = new List<Post>
                            {
                                new Post { Title = "Fish care 101" },
                                new Post { Title = "Caring for tropical fish" },
                                new Post { Title = "Types of ornamental fish" }
                            }
                        });

                    db.Blogs.Add(
                        new Blog
                        {
                            Name = "Cats Blog",
                            Url = "http://sample.com/blogs/cats",
                            Posts = new List<Post>
                            {
                                new Post { Title = "Cat care 101" },
                                new Post { Title = "Caring for tropical cats" },
                                new Post { Title = "Types of ornamental cats" }
                            }
                        });

                    db.Blogs.Add(
                        new Blog
                        {
                            Name = "Catfish Blog",
                            Url = "http://sample.com/blogs/catfish",
                            Posts = new List<Post>
                            {
                                new Post { Title = "Catfish care 101" }, new Post { Title = "History of the catfish name" }
                            }
                        });

                    db.SaveChanges();

                    db.Database.ExecuteSqlRaw(
                     @"CREATE VIEW View_BlogPosts AS
                            SELECT b.Name , b.BlogId, b.Url FROM Blogs b");
                }
            }
        }
    }

    public class BloggingContext : DbContext
    {
        private static readonly ILoggerFactory _loggerFactory
            = LoggerFactory.Create(
                builder => builder.AddConsole().AddFilter((c, l) => l == LogLevel.Information && !c.EndsWith("Connection")));

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

        public DbSet<BlogWithPosts> BlogWithPosts { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder
                .UseSqlServer(
                   // @"Server=(localdb)\mssqllocaldb;Database=Sample.KeylessEntityTypes;Trusted_Connection=True;ConnectRetryCount=0;")
                   @"Server=.\SQLEXPRESS;Database=test_view;Trusted_Connection=True;")
                .UseLoggerFactory(_loggerFactory);
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<BlogWithPosts>(eb =>
            {
                //eb.HasNoKey();
                eb.ToView("View_BlogPosts");
                eb.HasKey(bwp => bwp.BlogId);
                eb.Property(v => v.BlogName).HasColumnName("Name");

                eb
                .HasMany(bwp => bwp.Posts)
                .WithOne()
                .HasForeignKey(p => p.BlogId);
            });

            modelBuilder.Entity<Blog>(blog =>
            {
                blog.HasMany(bwp => bwp.Posts)
                .WithOne(b => b.Blog)
                .HasForeignKey(p => p.BlogId);
            });
        }
    }

    public class Blog
    {
        public int BlogId { get; set; }
        public string Name { get; set; }
        public string Url { get; set; }
        public ICollection<Post> Posts { get; set; }
    }

    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
        public int BlogId { get; set; }
        public Blog Blog { get; set; }
    }

    public class BlogWithPosts
    {
        public int BlogId { get; set; }
        public string BlogName { get; set; }
        public ICollection<Post> Posts { get; set; } = new List<Post>();
    }
}

此示例在 EF Core 5.0.2 上进行了测试,重要的是

暂无
暂无

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

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