简体   繁体   English

具有关系ID的EFCore保存实体

[英]EFCore save entity with relation ids

I'm trying to save an entity, but this entity is related to another one and of this one I only have the id. 我正在尝试保存一个实体,但是该实体与另一个实体相关,而这个实体我只有ID。 For example, giving this structure: 例如,给出以下结构:

public class Library
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<Book> Books { get; set; }
}

public class Book
{
    public int Id { get; set; }
    public int LibraryId { get; set; }
    public string Title { get; set; }
    public Bookshelf Bookshelf { get; set; }
}

public class Bookshelf
{
    public int Id { get; set; }
    public string Color { get; set; }
}

I receive from the client a new book to save to the db. 我从客户端收到一本新书,要保存到数据库。 This book only contains the Title , the LibraryId and the BookshelfId (it's a DTO). 本书仅包含TitleLibraryIdBookshelfId (这是DTO)。 Now I want to save this book, creating the relationship with Library and Bookshelf, without retrieving the full object Library and Bookshelf , how can I do it easily? 现在,我想保存这本书,并与Library and Bookshelf建立关系,而无需检索完整的Library and Bookshelf对象,如何轻松实现?

What if, for example, I want to create a new library, and relate it to some already existing books? 例如,如果我想创建一个新的图书馆并将其与一些已经存在的书联系起来怎么办? What I should do to achieve it? 我应该怎么做才能做到这一点?

I want to save this book, creating the relationship with Library and Bookshelf, without retrieving the full object Library and Bookshelf 我想保存这本书,与图书馆和书架建立关系,而无需检索整个对象图书馆和书架

Simply add a property BookshelfId on your book class. 只需在您的书本类中添加属性BookshelfId。

public class Book
{
    public int Id { get; set; }
    public int LibraryId { get; set; }
    public string Title { get; set; }
    public Bookshelf Bookshelf { get; set; }
    public int BookshelfId { get; set; }
}

Then you can do: 然后,您可以执行以下操作:

DbContext.Add(new Book { LibraryId = 1, BookshelfId = 1});
DbContext.SaveChanges();

What if, for example, I want to create a new library, and relate it to some already existing books 例如,如果我想创建一个新的图书馆并将其与一些已经存在的书相关联该怎么办?

Add Library navigation property on the book 在书上添加图书馆导航属性

public class Book
{
    public int Id { get; set; }
    public Library Library { get; set; }
    ...
}

and then you can update the library property on the books using only their ids 然后您可以仅使用它们的ID更新书上的图书馆属性

var library = new Library { Name = "My library" };
DbContext.Libraries.Add(library);

var bookIds = new int[] {1, 2};

foreach(var bookId in bookIds) {
    var book = new Book { Id= bookId, Library = library};
    DbContext.Attach(book);
    DbContext.Entry(book).Property(b => b.LibraryId).IsModified = true;
}

DbContext.SaveChanges();

Your Book Model will slightly change to reflect the relationship with the Library and BookShelf Models 您的Book模型会略有变化,以反映与LibraryBookShelf模型的关系

public class Book
{
  public int Id { get; set; }
  public string Title { get; set; }

  public int LibraryId { get; set; }
  public Library Library {get;set;} //navigation property to Library

  public Bookshelf Bookshelf { get; set; }
  public Bookshelf Bookshelf {get;set;} //navigation property to Bookshelf
}

The way i see you write your model means : a Book cannot be created without a Library but a library can be created without a Book . 我看到您编写模型的方式意味着:没有图书馆就无法创建Book但是没有Book就可以创建Library

This example I create a new library, new book shelf and new book without fetching any data. 在此示例中,我创建了一个新的库,新的书架和新的书​​,而没有获取任何数据。

My classes: 我的课程:

public class Library
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Book> Books { get; set; }
}

public class Bookshelf
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }
    public string Color { get; set; }
}

public class Book
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }
    public int LibraryId { get; set; }
    public string Title { get; set; }

    public int BookshelfId { get; set; }

    [ForeignKey("BookshelfId")]
    public virtual Bookshelf Bookshelf { get; set; }

    [ForeignKey("LibraryId")]
    public virtual Library Library { get; set; }
}

Saving new Book with new Library and new Bookshekf. 使用新的图书馆和新的Bookhekf保存新书。

var contextDb = new LabContextDb();

var newLibrary = new Library()
{                
   Id = 1,
   Name = "My new library",
};

newLibrary = contextDb.Libraries.Add(newLibrary).Entity;

 var newBookshelf = new Bookshelf() { Id = 2, Color = "Blue" };

 newBookshelf = contextDb.Bookshelves.Add(newBookshelf).Entity;

 var newBook = new Book()
 {
    Id = 5,
    Title = "My New Book",
    LibraryId = newLibrary.Id,
    Bookshelf = newBookshelf
  };

 contextDb.Books.Add(newBook);
 contextDb.SaveChanges();

Expected result 预期结果

在此处输入图片说明

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

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