如何在EF Core中添加父记录及其子记录 [英] How to add a parent record with its children records in EF Core

查看:207
本文介绍了如何在EF Core中添加父记录及其子记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的示例1曾经可以工作,但是在EF Core中不起作用.问题:如何使下面的示例2正常工作?

Example 1 below used to work but it is not working in EF Core. Question: How to make example 2 below work?

示例1 :

child c1 = new child();
child c2 = new child();

parent p=new parent();
p.child.Add(c1);
p.child.Add(c2);

using (var db = new DbContext())
{
   db.parent.Add(p);
   db.SaveChanges();
}

实体父P具有一对一关系的子C1和C2.尝试插入父项及其子项记录.但是在以下代码中, VS2017 的编辑器的 intellisense 在行 cust.child.Add(c1)处无法识别 .child .; .也许,EF Core在插入父/子记录方面有更好的选择.我正在使用ASP.NET MVC Core 1.1.1 和EF Core 1.1.1

Entity Parent P has children C1, and C2 in a one-to-one relationship. Trying to insert a parent and its children records. But in the following code VS2017's editor's intellisense does not recognize .child at the line cust.child.Add(c1);. Maybe, EF Core has something better for inserting parent/child records. I'm using ASP.NET MVC Core 1.1.1 and EF Core 1.1.1.

示例2 :

...
Parent p = new Parent { Name = "some name" , FY = SelectedYear, ... };

Child c1 = new Child { ItemName = "Abc"};
Child c2 = new Child { ItemName = "Rst"};

p.child.Add(c1);
p..child.Add(c2);

_context.Add(p);
_context.SaveChanges();

更新:

根据来自 @GlennSills 的请求,以下是著名的Blogging Db的示例(摘自

Per a request from @GlennSills, following is an example of well known Blogging Db (taken from this ASP.NET tutorial):

public class BloggingContext : DbContext
{
    public BloggingContext(DbContextOptions<BloggingContext> options)
        : base(options)
    { }

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

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

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

在下面的 Create(...)方法中,在 blog.Posts.Add(c); 行中,我得到了错误: Object reference not设置为对象的实例.

In the Create(...) method below, at line blog.Posts.Add(c); I get the error: Object reference not set to an instance of an object.

public class BlogsController : Controller
{
    private readonly BloggingContext _context;

    public BlogsController(BloggingContext context)
    {
        _context = context;    
    }
....
....
// POST: Blogs/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for 
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("BlogId,Url")] Blog blog)
{
    if (ModelState.IsValid)
    {
        Post c = new Post();
        blog.Posts.Add(c);

        _context.Add(blog);
        await _context.SaveChangesAsync();
        return RedirectToAction("Index");
    }
    return View(blog);
}
}

推荐答案

将子对象与其父对象一起保存绝对有效.关键是您需要以EF知道所有关系的方式对实体建模.这是一个非常简单的应用程序,您可以看一下. github上的简单应用

Saving child objects along with their parent definitely works. The key is you need to model your entities in such a way that EF knows about all the relationships. Here is a really simple application doing it that you can take a look at. Simple app on github

我有一个看起来像的父母

I have a parent that looks like

using System.Collections.Generic;

namespace EFParentChild
{
    public class Parent
    {
        public int ParentId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public List<Child> Children { get; set; } = new List<Child>();
    }
}

这是孩子

namespace EFParentChild
{
    public class Child
    {
        public int Id { get; set; }
        public int ParentId { get; set; }
        public Parent Parent { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
}

这里是上下文:

使用Microsoft.EntityFrameworkCore;

using Microsoft.EntityFrameworkCore;

namespace EFParentChild
{
  class DbParentChild : DbContext
  {
    public DbSet<Parent> Parents { get; set; }
    public DbSet<Child> Children { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=ParentChildDb;Trusted_Connection=True;");
    }

  }
}

这是保存数据的程序

static void Main(string[] args)
    {
        using (var dbContext = new DbParentChild())
        {
            var parent = new Parent
            {
                FirstName = "Joe",
                LastName = "Smith"
            };

            parent.Children.Add(
                new Child
                {
                    FirstName = "LittleJoe",
                    LastName = "Smith"
                });
            parent.Children.Add(
                new Child
                {
                    FirstName = "Anne",
                    LastName = "Smith"
                });

            dbContext.Add(parent);
            dbContext.SaveChanges();
        }
    }

这里的关键是我正在使用约定来告诉EF亲子关系.请注意,两个实体之间使用的ID名称是如何匹配的.子代具有与其父代中的ParentId相匹配的ParentId.还注意到子项中的外键约束.

The key here is that I'm using conventions to tell EF that there is a parent-child relations. Notice how the id names used between the two entities match up. The child has a ParentId that matches ParentId in its parent. Also noticed the foreign key constraint in the child.

我使用实体框架工具创建了表.您可以自己采用这种方法,也可以根据需要手工创建它们.父DDL是:

I created the tables using the entity framework tooling. You can take that approach yourself or create them by hand if you want. The parent DDL is :

CREATE TABLE [dbo].[Parents] (
[ParentId]  INT            IDENTITY (1, 1) NOT NULL,
[FirstName] NVARCHAR (MAX) NULL,
[LastName]  NVARCHAR (MAX) NULL,
CONSTRAINT [PK_Parents] PRIMARY KEY CLUSTERED ([ParentId] ASC)
);

子DDL为:

CREATE TABLE [dbo].[Children] (
[Id]        INT            IDENTITY (1, 1) NOT NULL,
[FirstName] NVARCHAR (MAX) NULL,
[LastName]  NVARCHAR (MAX) NULL,
[ParentId]  INT            NOT NULL,
CONSTRAINT [PK_Children] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_Children_Parents_ParentId] FOREIGN KEY ([ParentId]) 
REFERENCES [dbo].[Parents] ([ParentId]) ON DELETE CASCADE
);


GO
CREATE NONCLUSTERED INDEX [IX_Children_ParentId]
  ON [dbo].[Children]([ParentId] ASC);

这篇关于如何在EF Core中添加父记录及其子记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆