【问题标题】:EFCore save entity with relation idsEFCore 保存具有关系 id 的实体
【发布时间】:2019-06-08 08:48:40
【问题描述】:

我正在尝试保存一个实体,但该实体与另一个实体相关,而在这个实体中,我只有 id。例如,给出这个结构:

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

我从客户那里收到一本要保存到数据库的新书。这本书只包含TitleLibraryIdBookshelfId(它是一个 DTO)。 现在我想保存这本书,创建与图书馆和书架的关系,而不检索完整的对象LibraryBookshelf,如何轻松做到?

例如,如果我想创建一个新图书馆,并将其与一些已经存在的书籍相关联,该怎么办?我应该怎么做才能实现它?

【问题讨论】:

  • 我建议您创建对 Library 对象的引用。创建新属性: public Library Library { get;放;并使用包括图书馆和书架来获取您的书。之后,您更新您的实体并应用所需的更改。要创建一个新的库,请创建一个库对象的新实例,将其添加到您的数据库 (ContextDb) 并将其设置为名为 Library 的新 Book 属性,并保存带有更改的 Book 对象。
  • 取书?第一个问题中的书是我想要创建的,所以我无法获取它。另外我希望书内的属性LibraryId 就足够了,而不必创建整个属性库
  • 我认为本文档可以解释您可以使用“保存相关数据”做什么。 docs.microsoft.com/en-us/ef/core/saving/related-data。祝你好运。
  • 不是真的,我希望通过相关实体的 ID,我能够创建关系。我需要检索完整的对象 Library 和 Bookshelf 并且需要将它们设置在书上,这真的很奇怪。
  • 将新图书馆添加到您的数据库中:yourContextDb.Add(new Library { LibraryId = 1, Name = "New Library"}) 并使用新图书馆的 ID 保存您的新书。跨度>

标签: c# entity-framework asp.net-core entity-framework-core


【解决方案1】:

我想保存这本书,创建与图书馆和书架的关系,而不检索完整的对象图书馆和书架

只需在您的图书类上添加一个属性 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; }
    ...
}

然后您可以仅使用它们的 id 更新图书上的 library 属性

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

【讨论】:

  • 第一个,我会尽快尝试。对于第二个,有没有办法在不检索书籍对象的情况下做到这一点,而只能使用它们的 id?
  • 第一个为我正确保存了具有关系的实体。但是当我拿到这本书时,BookshelfId 是正确的,但 Bookshelf 是空的。
【解决方案2】:

您的 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
}

我看到您编写模型的方式意味着:没有Library 就无法创建Book,但没有Book 可以创建库。

【讨论】:

  • 是的,一本书需要一个图书馆。但是这个呢?如何保存一本新书,并将其与现有图书馆相关联,只知道 libraryId,而不获取整个图书馆?
【解决方案3】:

这个例子我在不获取任何数据的情况下创建了一个新图书馆、新书架和新书。

我的课:

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

用新图书馆和新书库保存新书。

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

预期结果

【讨论】:

    猜你喜欢
    • 2019-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    • 2021-03-27
    • 2021-08-18
    相关资源
    最近更新 更多