EFCore сохранить сущность с идентификаторами отношений - PullRequest
0 голосов
/ 08 июня 2019

Я пытаюсь сохранить сущность, но эта сущность связана с другой, и у меня есть только идентификатор. Например, давая эту структуру:

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

Я получаю от клиента новую книгу для сохранения в БД. Эта книга содержит только Title, LibraryId и BookshelfId (это DTO). Теперь я хочу сохранить эту книгу, создав отношения с Библиотекой и Книжной полкой, не извлекая полный объект Library и Bookshelf, как мне это легко сделать?

Что, если, например, я хочу создать новую библиотеку и связать ее с некоторыми уже существующими книгами? Что я должен сделать, чтобы достичь этого?

Ответы [ 3 ]

1 голос
/ 08 июня 2019

Я хочу сохранить эту книгу, создав отношения с библиотекой и книжной полкой, не извлекая полный объект Библиотека и книжная полка

Просто добавьте свойство 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; }
}

Затем вы можете сделать:

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

Что если, например, я хочу создать новую библиотеку и связать ее с некоторыми уже существующими книгами

Добавить свойство навигации библиотеки в книге

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

, а затем вы можете обновить свойство библиотеки в книгах, используя только их идентификаторы

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();
0 голосов
/ 08 июня 2019

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

Мои занятия:

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

Сохранение новой книги с новой библиотекой и новым Bookshekf.

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

Ожидаемый результат

enter image description here

0 голосов
/ 08 июня 2019

Ваша Book модель немного изменится, чтобы отразить связь с моделями Library и BookShelf

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
}

То, как вы пишете свою модель, означает: Book нельзя создать без Library, а библиотеку можно создать без Book.

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