たとえば、3つのクラスがあり、多対多の関係に使用しています。
public class Library
{
[Key]
public string LibraryId { get; set; }
public List<Library2Book> Library2Books { get; set; }
}
public class Book
{
[Key]
public string BookId { get; set; }
public List<Library2Book> Library2Books { get; set; }
}
public class Library2Book
{
public string BookId { get; set; }
public Book Book { get; set; }
public string LibraryId { get; set; }
public Library Library { get; set; }
}
それらはApplicationDbContext
で設定されます:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<CodeableConcept2Coding>().HasKey(k => new { k.LibraryId, k.BookId });
builder.Entity<Library2Book>()
.HasOne(x => x.Library)
.WithMany(x => x.Library2Book)
.HasForeignKey(x => x.LibraryId);
builder.Entity<Library2Book>()
.HasOne(x => x.Book)
.WithMany(x => x.Library2Book)
.HasForeignKey(x => x.BookId);
}
だから、データベースにLibrary2Books
のリストを追加したい:
var library2Books = new List<Library2Books>(/*some sort of initialization*/);
最初にどのエンティティを追加する必要がありますか? Books
またはLibrary
?この保存を行うにはどうすればよいですか?
これは、EF Coreの多対多の関係に対する単純で非常に基本的な質問です。 EF Coreでn..mの完全な例を誰も書いていない理由がわかりません。
コードを変更しました(int
としての主キー)。主キーの文字列が好きではありません。コードをコピーして貼り付けるだけで、すべて正常に動作するはずです。
最初にどのエンティティを追加する必要がありますか?本か図書館か?この保存を行うにはどうすればよいですか?
順序は重要ではありませんが、ここで重要なのはデータのリンクです。データは正しくリンクされている必要があります。コード行間のコメントを参照してください。
ノート:
結合テーブルを表すエンティティクラスのない多対多の関係はまだサポートされていません!結合テーブルが必要です。
多対多の関係は、2つの個別の1対多の関係で構成されます。 = 2x 1:N
class Program
{
public class Library
{
[Key]
public int LibraryId { get; set; }
public List<Library2Book> Library2Books { get; set; } = new List<Library2Book>();
}
public class Book
{
[Key]
public int BookId { get; set; }
public List<Library2Book> Library2Books { get; set; } = new List<Library2Book>();
}
public class Library2Book
{
[Key]
public int BookId { get; set; }
public Book Book { get; set; }
[Key]
public int LibraryId { get; set; }
public Library Library { get; set; }
}
public class MyDbContext : DbContext
{
public DbSet<Book> Books { get; set; }
public DbSet<Library> Libraries { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Server=.\;Database=EFTutorial;integrated security=True;");
base.OnConfiguring(optionsBuilder);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Library2Book>().HasKey(k => new { k.LibraryId, k.BookId });
modelBuilder.Entity<Library2Book>()
.HasOne(x => x.Book)
.WithMany(x => x.Library2Books)
.HasForeignKey(x => x.BookId);
modelBuilder.Entity<Library2Book>()
.HasOne(x => x.Library)
.WithMany(x => x.Library2Books)
.HasForeignKey(x => x.LibraryId);
base.OnModelCreating(modelBuilder);
}
}
static void Main(string[] args)
{
using (var myDb = new MyDbContext())
{
// Create Db
myDb.Database.EnsureCreated();
// I will add two books to one library
var book1 = new Book();
var book2 = new Book();
// I create the library
var lib = new Library();
// I create two Library2Book which I need them
// To map between the books and the library
var b2lib1 = new Library2Book();
var b2lib2 = new Library2Book();
// Mapping the first book to the library.
// Changed b2lib2.Library to b2lib1.Library
b2lib1.Book = book1;
b2lib1.Library = lib;
// I map the second book to the library.
b2lib2.Book = book2;
b2lib2.Library = lib;
// Linking the books (Library2Book table) to the library
lib.Library2Books.Add(b2lib1);
lib.Library2Books.Add(b2lib2);
// Adding the data to the DbContext.
myDb.Libraries.Add(lib);
myDb.Books.Add(book1);
myDb.Books.Add(book2);
// Save the changes and everything should be working!
myDb.SaveChanges();
}
}
}
結果
Tables: Books | Libraries | Library2Book |
1 | 1 | 1 | 1 |
2 | - | 1 | 2 |
質問の著者から編集
多くのエンティティを挿入しようとすると(約300を試しました)、同じキーが既に追加されていますエラーになります。挿入コレクションを小さな部分に分割する必要があります。 100個のエンティティで十分です。
public async Task SaveEntities(IEnumerable<Library2Book> library2Books)
{
int i = 0;
foreach (var library2Book in library2Books)
{
_dbContext.Set<Library>().Add(codConc2Coding.Library);
_dbContext.Set<Book>().Add(codConc2Coding.Book);
_dbContext.Set<Library2Book>().Add(library2Book);
i++;
if (i == 99)
{
await _dbContext.SaveChangesAsync();
i = 0;
}
}
await _dbContext.SaveChangesAsync();
}