Kerangka Entitas: Satu Basis Data, Beberapa DbKonteks. Apakah ini ide yang buruk? [Tutup]


213

Kesan saya sampai saat ini adalah bahwa a DbContextdimaksudkan untuk mewakili basis data Anda, dan dengan demikian, jika aplikasi Anda menggunakan satu basis data, Anda hanya menginginkan satu DbContext.

Namun, beberapa rekan ingin membagi area fungsional ke dalam DbContextkelas yang terpisah .

Saya percaya ini berasal dari tempat yang baik - keinginan untuk menjaga kode lebih bersih - tetapi tampaknya tidak stabil. Naluriku mengatakan itu adalah ide yang buruk, tapi sayangnya, naluriku bukanlah kondisi yang cukup untuk keputusan desain.

Jadi saya mencari:

A) contoh nyata mengapa ini bisa menjadi ide yang buruk;

B) menjamin bahwa ini semua akan berjalan dengan baik.


Jawaban:


168

Anda dapat memiliki banyak konteks untuk satu basis data. Sebagai contoh, ini dapat berguna jika basis data Anda mengandung banyak skema basis data dan Anda ingin menangani masing-masingnya sebagai area mandiri yang terpisah.

Masalahnya adalah ketika Anda ingin menggunakan kode terlebih dahulu untuk membuat database Anda - hanya konteks tunggal dalam aplikasi Anda yang bisa melakukannya. Trik untuk ini biasanya satu konteks tambahan yang mengandung semua entitas Anda yang hanya digunakan untuk pembuatan basis data. Konteks aplikasi nyata Anda yang hanya berisi himpunan bagian entitas Anda harus memiliki penginisialisasi basis data yang disetel ke nol.

Ada masalah lain yang akan Anda lihat ketika menggunakan beberapa tipe konteks - misalnya tipe entitas bersama dan perpindahannya dari satu konteks ke konteks lainnya, dll. Secara umum dimungkinkan, itu dapat membuat desain Anda jauh lebih bersih dan memisahkan area fungsional yang berbeda tetapi memiliki biaya dalam kompleksitas tambahan.


21
Menggunakan konteks tunggal per aplikasi bisa mahal jika aplikasi memiliki banyak entitas / tabel. Jadi tergantung pada skema, mungkin juga masuk akal untuk memiliki banyak konteks.
DarthVader

7
Karena saya tidak berlangganan pluralsight, saya menemukan artikel yang luar biasa ini oleh Julie Lerman ( komentarnya ) ditulis dengan baik setelah tanya jawab ini, tetapi sangat tepat: msdn.microsoft.com/en-us/magazine/jj883952.aspx
Dave T.

Saya menyarankan, kerangka kerja entitas untuk mendukung beberapa dbcontexts dalam database yang sama dengan penamaan konvensi. Untuk alasan ini saya masih menulis ORM saya sendiri untuk keperluan aplikasi modular. Itu sulit untuk percaya itu memaksa aplikasi tunggal untuk menggunakan database tunggal. Terutama di peternakan web Anda telah jumlah database terbatas
sukarela

Selain itu, saya menyadari bahwa Anda dapat Mengaktifkan-Migrasi hanya untuk satu konteks di dalam proyek melalui PM Console.
Piotr Kwiatek

9
@PiotrKwiatek Tidak yakin apakah ini berubah antara komentar Anda dan sekarang, tetapi Enable-Migrations -ContextTypeName MyContext -MigrationsDirectory Migrations\MyContextMigrationsberfungsi sekarang.
Zack

60

Saya menulis jawaban ini sekitar empat tahun lalu dan pendapat saya belum berubah. Namun sejak itu ada perkembangan signifikan di bidang layanan mikro. Saya menambahkan catatan spesifik layanan mikro di akhir ...

Saya akan mempertimbangkan ide itu, dengan pengalaman dunia nyata untuk mendukung suara saya.

Saya dibawa ke aplikasi besar yang memiliki lima konteks untuk satu database. Pada akhirnya, kami akhirnya menghapus semua konteks kecuali satu - kembali ke satu konteks.

Pada awalnya ide tentang berbagai konteks sepertinya ide yang bagus. Kami dapat memisahkan akses data kami ke dalam domain dan menyediakan beberapa konteks ringan bersih. Kedengarannya seperti DDD, kan? Ini akan menyederhanakan akses data kami. Argumen lain adalah untuk kinerja karena kita hanya mengakses konteks yang kita butuhkan.

Namun dalam praktiknya, seiring pertumbuhan aplikasi kami, banyak dari tabel kami berbagi hubungan di berbagai konteks kami. Misalnya, kueri ke tabel A dalam konteks 1 juga diminta bergabung dengan tabel B dalam konteks 2.

Ini meninggalkan kita dengan beberapa pilihan yang buruk. Kita bisa menduplikasi tabel dalam berbagai konteks. Kami mencoba ini. Ini menciptakan beberapa masalah pemetaan termasuk kendala EF yang mengharuskan setiap entitas memiliki nama yang unik. Jadi kami berakhir dengan entitas bernama Person1 dan Person2 dalam konteks yang berbeda. Orang dapat berargumen bahwa ini adalah desain yang buruk di pihak kami, tetapi terlepas dari upaya terbaik kami, ini adalah bagaimana aplikasi kami sebenarnya tumbuh di dunia nyata.

Kami juga mencoba menanyakan kedua konteks untuk mendapatkan data yang kami butuhkan. Misalnya, logika bisnis kami akan meminta setengah dari yang diperlukan dari konteks 1 dan setengah lainnya dari konteks 2. Ini memiliki beberapa masalah besar. Alih-alih melakukan satu permintaan terhadap satu konteks, kami harus melakukan beberapa permintaan di berbagai konteks. Ini memiliki penalti performa nyata.

Pada akhirnya, kabar baiknya adalah mudah untuk menghapus berbagai konteks. Konteksnya dimaksudkan untuk menjadi objek yang ringan. Jadi saya tidak berpikir kinerja adalah argumen yang bagus untuk banyak konteks. Dalam hampir semua kasus, saya percaya satu konteks lebih sederhana, lebih kompleks, dan kemungkinan akan berkinerja lebih baik, dan Anda tidak perlu menerapkan banyak upaya untuk membuatnya bekerja.

Saya memikirkan satu situasi di mana banyak konteks bisa berguna. Konteks terpisah dapat digunakan untuk memperbaiki masalah fisik dengan database yang sebenarnya berisi lebih dari satu domain. Idealnya, konteks akan menjadi satu-ke-satu ke domain, yang akan menjadi satu-ke-satu ke database. Dengan kata lain, jika satu set tabel sama sekali tidak terkait dengan tabel lain dalam database yang diberikan, mereka mungkin harus ditarik ke dalam database yang terpisah. Saya menyadari ini tidak selalu praktis. Tetapi jika satu set tabel sangat berbeda sehingga Anda akan merasa nyaman memisahkan mereka ke dalam database yang terpisah (tetapi Anda memilih untuk tidak melakukannya) maka saya dapat melihat kasus untuk menggunakan konteks yang terpisah, tetapi hanya karena sebenarnya ada dua domain yang terpisah.

Mengenai layanan mikro, satu konteks tunggal masih masuk akal. Namun, untuk layanan mikro, setiap layanan akan memiliki konteksnya sendiri yang hanya mencakup tabel basis data yang relevan dengan layanan itu. Dengan kata lain, jika layanan x mengakses tabel 1 dan 2, dan layanan y mengakses tabel 3 dan 4, setiap layanan akan memiliki konteks uniknya sendiri yang mencakup tabel khusus untuk layanan tersebut.

Saya tertarik dengan pemikiran Anda.


8
Saya harus setuju di sini, terutama ketika menargetkan basis data yang ada. Saya sedang mengerjakan masalah ini sekarang, dan firasat saya sejauh ini adalah: 1. Memiliki tabel fisik yang sama dalam berbagai konteks adalah ide yang buruk. 2. Jika kita tidak dapat memutuskan bahwa sebuah tabel termasuk dalam satu konteks atau lainnya, maka kedua konteks tersebut tidak cukup berbeda untuk dipisahkan secara logis.
jkerak

3
Saya berpendapat bahwa, ketika melakukan CQRS, Anda tidak akan memiliki hubungan antara konteks (setiap tampilan dapat memiliki konteksnya sendiri) sehingga peringatan ini tidak berlaku untuk setiap kasus ketika seseorang mungkin ingin memiliki banyak konteks. Alih-alih bergabung dan referensi, gunakan duplikasi data untuk setiap konteks. - Ini tidak meniadakan kegunaan dari jawaban ini :)
urbanhusky

1
Saya merasakan sakit yang Anda hadapi dalam! : / Saya juga berpikir satu konteks adalah pilihan yang lebih baik untuk kesederhanaan.
ahmet

1
Argumen saya satu-satunya yang menentang, dengan catatan bahwa saya sebaliknya sepenuhnya setuju, adalah mengenai Identitas. Terutama dengan penskalaan horizontal, lapisan identitas perlu dipisahkan di hampir semua kasus di mana penyeimbangan beban diperkenalkan. Setidaknya, itulah yang saya temukan.
Barry

5
Bagi saya sepertinya Anda tidak menggunakan DDD sepenuhnya, jika agregat Anda perlu mengetahui agregat lain. Jika Anda perlu referensi sesuatu ada dua alasan mengapa: mereka berada di agregat yang sama yang berarti mereka harus diubah dalam transaksi yang sama atau tidak dan Anda salah batas Anda.
Simons0n

54

Utas ini baru saja menggelegak di StackOverflow dan jadi saya ingin menawarkan jaminan "B) lain bahwa ini semua akan baik-baik saja" :)

Saya melakukan ini persis dengan pola DDD Bounded Context. Saya telah menulisnya di buku saya, Programming Entity Framework: DbContext dan itu adalah fokus modul 50 menit dalam salah satu kursus saya di Pluralsight -> http://pluralsight.com/training/Courses/TableOfContents/efarchitecture


7
Video pelatihan pluralsight sangat baik dalam menjelaskan konsep-konsep besar namun, ya, contoh yang Anda berikan terlalu sepele dibandingkan dengan solusi perusahaan, (di mana misalnya NuGet rakitan dengan definisi DbContext ada, atau rakitan modular memuat secara dinamis.) DDD Bounded Context benar-benar rusak oleh contoh terakhir Anda di mana DbContext duplikat didefinisikan untuk menyimpan deklarasi duplikat untuk setiap DbSet. Saya menghargai bahwa Anda dibatasi oleh teknologinya. Saya benar-benar menyukai video Anda, tetapi ini membuat saya menginginkan lebih.
Victor Romeo

5
Saya ingin membidik gambaran besar. masalah paket re nuget di aplikasi Besar cukup di luar konteks untuk video ef. Contoh "rusak" Hah? Mungkin lebih baik untuk membawa ini ke obrolan pribadi karena kritik terhadap kursus saya cukup di luar jangkauan (dan mungkin tidak sesuai) untuk forum ini. Saya pikir SO memungkinkan Anda menghubungi saya secara langsung.
Julie Lerman

57
Pasti menyenangkan jika Julie membagikan beberapa info tentang masalah / pertanyaan OP. Alih-alih, pos ini hanya untuk mempromosikan langganan berbayar ke pluralinsight. Jika sebuah plug untuk suatu produk, setidaknya tautan ke info pada solusi yang disarankan (DDD Bounded context Pattern) akan sangat membantu. Apakah 'DDD' apa yang dijelaskan pada hal.222 dari "Kerangka Kerja Pemrograman Entitas: DBContext"? Karena saya mencari (tidak ada indeks) untuk 'DDD' atau bahkan 'Bounded Context', dan tidak dapat menemukan ... Tidak dapat menunggu Anda untuk membuat revisi baru untuk EF6 ...
Narcissist Compassionate Narcissist

12
maaf, saya tidak mencoba untuk mempromosikan, hanya menambah OP "ingin jaminan". Ladislav dan yang lainnya melakukan pekerjaan dengan detail. Jadi saya hanya mencoba sesuatu yang sudah saya buat yang jauh lebih dalam daripada yang bisa saya sampaikan pada SO. Berikut adalah sumber daya lain tempat saya membahas beberapa hal terkait: msdn.microsoft.com/en-us/magazine/jj883952.aspx & msdn.microsoft.com/en-us/magazine/dn342868.aspx & oredev.org / 2013 / wed-fri-conference / ...
Julie Lerman

ringkasan saran kode @JulieLerman lihat jawaban saya stackoverflow.com/a/36789520/1586498
OzBob

46

Membedakan konteks dengan mengatur skema default

Di EF6 Anda dapat memiliki beberapa konteks, cukup tentukan nama untuk skema database default dalam OnModelCreatingmetode DbContextkelas yang Anda peroleh (di mana konfigurasi Fluent-API adalah). Ini akan bekerja di EF6:

public partial class CustomerModel : DbContext
{   
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema("Customer");

        // Fluent API configuration
    }   
}

Contoh ini akan menggunakan "Pelanggan" sebagai awalan untuk tabel basis data Anda (bukan "dbo"). Lebih penting lagi, ini juga akan mengawali __MigrationHistorytabel, misalnya Customer.__MigrationHistory. Jadi Anda dapat memiliki lebih dari satu __MigrationHistorytabel dalam satu database, satu untuk setiap konteks. Jadi perubahan yang Anda buat untuk satu konteks tidak akan berantakan dengan yang lain.

Saat menambahkan migrasi, tentukan nama yang sepenuhnya memenuhi syarat kelas konfigurasi Anda (berasal dari DbMigrationsConfiguration) sebagai parameter dalam add-migrationperintah:

add-migration NAME_OF_MIGRATION -ConfigurationTypeName FULLY_QUALIFIED_NAME_OF_CONFIGURATION_CLASS


Sebuah kata pendek pada tombol konteks

Menurut artikel MSDN ini " Bab - Banyak Model Menargetkan Database yang Sama " EF 6 mungkin akan menangani situasi bahkan jika hanya ada satu MigrationHistorytabel, karena dalam tabel terdapat kolom ContextKey untuk membedakan migrasi.

Namun saya lebih suka memiliki lebih dari satu MigrationHistorytabel dengan menentukan skema default seperti yang dijelaskan di atas.


Menggunakan folder migrasi terpisah

Dalam skenario seperti itu Anda mungkin juga ingin bekerja dengan folder "Migrasi" yang berbeda di proyek Anda. Anda dapat mengatur DbMigrationsConfigurationkelas turunan Anda sesuai dengan menggunakan MigrationsDirectoryproperti:

internal sealed class ConfigurationA : DbMigrationsConfiguration<ModelA>
{
    public ConfigurationA()
    {
        AutomaticMigrationsEnabled = false;
        MigrationsDirectory = @"Migrations\ModelA";
    }
}

internal sealed class ConfigurationB : DbMigrationsConfiguration<ModelB>
{
    public ConfigurationB()
    {
        AutomaticMigrationsEnabled = false;
        MigrationsDirectory = @"Migrations\ModelB";
    }
}


Ringkasan

Semua dalam semua, Anda dapat mengatakan bahwa semuanya dipisahkan dengan bersih: Konteks, folder Migrasi dalam proyek dan tabel dalam database.

Saya akan memilih solusi seperti itu, jika ada kelompok entitas yang merupakan bagian dari topik yang lebih besar, tetapi tidak terkait (melalui kunci asing) satu sama lain.

Jika kelompok-kelompok entitas tidak memiliki sesuatu untuk dilakukan satu sama lain, saya akan membuat database terpisah untuk masing-masing dan mengaksesnya dalam proyek yang berbeda, mungkin dengan satu konteks tunggal di setiap proyek.


Apa yang Anda lakukan ketika Anda perlu memperbarui 2 entitas yang berada dalam konteks yang berbeda?
sotn

Saya akan membuat kelas (layanan) baru yang tahu konteks keduanya, memikirkan nama baik dan tanggung jawab kelas ini dan melakukan pembaruan ini dalam salah satu metode.
Martin

7

Contoh sederhana untuk mencapai di bawah ini:

    ApplicationDbContext forumDB = new ApplicationDbContext();
    MonitorDbContext monitor = new MonitorDbContext();

Hanya lingkup properti dalam konteks utama: (digunakan untuk membuat dan memelihara DB) Catatan: Cukup gunakan protected: (Entitas tidak diekspos di sini)

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("QAForum", throwIfV1Schema: false)
    {

    }
    protected DbSet<Diagnostic> Diagnostics { get; set; }
    public DbSet<Forum> Forums { get; set; }
    public DbSet<Post> Posts { get; set; }
    public DbSet<Thread> Threads { get; set; }
    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
    }
}

MonitorContext: Paparkan Entitas terpisah di sini

public class MonitorDbContext: DbContext
{
    public MonitorDbContext()
        : base("QAForum")
    {

    }
    public DbSet<Diagnostic> Diagnostics { get; set; }
    // add more here
}

Model diagnostik:

public class Diagnostic
{
    [Key]
    public Guid DiagnosticID { get; set; }
    public string ApplicationName { get; set; }
    public DateTime DiagnosticTime { get; set; }
    public string Data { get; set; }
}

Jika Anda suka, Anda dapat menandai semua entitas sebagai terlindungi di dalam ApplicationDbContext utama, lalu buat konteks tambahan yang diperlukan untuk setiap pemisahan skema.

Mereka semua menggunakan string koneksi yang sama, namun mereka menggunakan koneksi terpisah, jadi jangan lintas transaksi dan waspadai masalah penguncian. Umumnya pemisahan desain Anda jadi ini seharusnya tidak terjadi.


2
Ini banyak membantu. Konteks "sekunder" tidak perlu mendeklarasikan tabel bersama. Cukup tambahkan DbSet<x>definisi itu secara manual . Saya melakukannya di kelas parsial yang sesuai dengan apa yang dibuat oleh Desainer EF.
Glen Little

Anda menyelamatkan saya banyak sakit kepala, tuan! Anda memberikan solusi konkret alih-alih jawaban yang diterima. Sangat dihargai!
WoIIe

6

Pengingat: Jika Anda menggabungkan beberapa konteks, pastikan Anda memotong dan menempelkan semua fungsi di berbagai RealContexts.OnModelCreating()Anda ke dalam tunggal Anda CombinedContext.OnModelCreating().

Saya hanya membuang-buang waktu untuk mencari tahu mengapa hubungan penghapusan kaskade saya tidak dipertahankan hanya untuk mengetahui bahwa saya belum memindahkan modelBuilder.Entity<T>()....WillCascadeOnDelete();kode dari konteks saya yang sebenarnya ke dalam konteks gabungan saya.


6
Daripada memotong dan menempel, bisakah Anda menelepon OtherContext.OnModelCreating()dari konteks gabungan Anda?
AlexFoxGill

4

Naluri saya mengatakan hal yang sama ketika saya menemukan desain ini.

Saya sedang mengerjakan basis kode di mana ada tiga dbContexts ke satu database. 2 dari 3 dbcontext bergantung pada informasi dari 1 dbcontext karena ini menyajikan data administratif. Desain ini telah menempatkan kendala pada bagaimana Anda dapat meminta data Anda. Saya mengalami masalah ini di mana Anda tidak dapat bergabung di seluruh dbcontexts. Alih-alih apa yang harus Anda lakukan adalah meminta dua dbcontext yang terpisah kemudian melakukan join di memori atau beralih melalui keduanya untuk mendapatkan kombinasi keduanya sebagai hasil yang ditetapkan. Masalah dengan itu alih-alih meminta untuk hasil tertentu yang ditetapkan Anda sekarang memuat semua catatan Anda ke dalam memori dan kemudian melakukan gabungan terhadap dua set hasil dalam memori. Ini benar-benar dapat memperlambat segalanya.

Saya akan mengajukan pertanyaan "hanya karena Anda bisa, bukan? "

Lihat artikel ini untuk masalah yang saya temui terkait dengan desain ini. Ekspresi LINQ yang ditentukan berisi referensi ke kueri yang terkait dengan konteks yang berbeda


3
Saya telah bekerja pada sistem besar di mana kami memiliki banyak konteks. Salah satu hal yang saya temukan adalah bahwa kadang-kadang Anda harus memasukkan DbSet yang sama dalam berbagai konteks. Di satu sisi ini memecahkan beberapa masalah kemurnian, tetapi itu memungkinkan Anda untuk menyelesaikan pertanyaan Anda. Untuk kasus di mana ada tabel admin tertentu yang perlu Anda baca, Anda bisa menambahkannya ke kelas DbContext dasar dan mewarisinya dalam konteks modul aplikasi Anda. Tujuan "nyata" admin konteks Anda mungkin didefinisikan ulang sebagai "menyediakan pemeliharaan untuk tabel admin", daripada menyediakan semua akses ke sana.
JMarsch

1
Untuk apa nilainya, saya selalu bolak-balik tentang apakah itu layak. Di satu sisi, dengan konteks yang terpisah, ada sedikit yang perlu diketahui untuk dev yang hanya ingin bekerja pada satu modul, dan Anda merasa lebih aman mendefinisikan dan menggunakan proyeksi kustom (karena Anda tidak khawatir tentang efeknya pada yang lain modul). Di sisi lain, Anda mengalami beberapa masalah saat Anda perlu berbagi data lintas konteks.
JMarsch

1
Anda tidak HARUS menyertakan entitas di kedua Anda selalu bisa mendapatkan id dan melakukan kueri ke-2 untuk konteks yang berbeda. Untuk sistem kecil ini buruk, untuk DB / sistem yang lebih besar dengan banyak koherensi devs dari struktur multi-tabel adalah masalah yang jauh lebih besar dan lebih sulit daripada 2 kueri.
user1496062

4

Terinspirasi oleh Artikel DDD MSDN Mag [@JulieLerman 2013] [1]

    public class ShippingContext : BaseContext<ShippingContext>
{
  public DbSet<Shipment> Shipments { get; set; }
  public DbSet<Shipper> Shippers { get; set; }
  public DbSet<OrderShippingDetail> Order { get; set; } //Orders table
  public DbSet<ItemToBeShipped> ItemsToBeShipped { get; set; }
  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
    modelBuilder.Ignore<LineItem>();
    modelBuilder.Ignore<Order>();
    modelBuilder.Configurations.Add(new ShippingAddressMap());
  }
}

public class BaseContext<TContext>
  DbContext where TContext : DbContext
{
  static BaseContext()
  {
    Database.SetInitializer<TContext>(null);
  }
  protected BaseContext() : base("DPSalesDatabase")
  {}
}   

"Jika Anda melakukan pengembangan baru dan Anda ingin membiarkan Code First membuat atau memigrasi basis data Anda berdasarkan kelas Anda, Anda harus membuat" model-uber "menggunakan DbContext yang mencakup semua kelas dan hubungan yang diperlukan untuk membangun model lengkap yang mewakili database. Namun, konteks ini tidak boleh diwarisi dari BaseContext. " JL


2

Dalam kode terlebih dahulu, Anda dapat memiliki beberapa DBContext dan hanya satu database. Anda hanya perlu menentukan string koneksi di konstruktor.

public class MovieDBContext : DbContext
{
    public MovieDBContext()
        : base("DefaultConnection")
    {

    }
    public DbSet<Movie> Movies { get; set; }
}

Ya Anda bisa, tetapi bagaimana Anda bisa meminta dari entitas yang berbeda dari konteks db yang berbeda?
Reza

2

Sedikit "kebijaksanaan". Saya memiliki basis data yang menghadap ke internet, dan aplikasi internal. Saya memiliki konteks untuk setiap wajah. Itu membantu saya untuk menjaga pemisahan, disiplin aman.


1

Saya ingin membagikan sebuah kasus, di mana saya pikir kemungkinan memiliki beberapa DBContexts dalam database yang sama masuk akal.

Saya punya solusi dengan dua database. Salah satunya adalah untuk data domain kecuali informasi pengguna. Yang lain hanya untuk informasi pengguna. Divisi ini terutama didorong oleh Peraturan Perlindungan Data Umum UE . Dengan memiliki dua basis data, saya dapat dengan bebas memindahkan data domain (misalnya dari Azure ke lingkungan pengembangan saya) selama data pengguna tetap berada di satu tempat yang aman.

Sekarang untuk basis data pengguna, saya telah menerapkan dua skema melalui EF. Satu adalah standar yang disediakan oleh kerangka kerja AspNet Identity. Yang lain adalah kami sendiri menerapkan hal lain yang terkait pengguna. Saya lebih suka solusi ini daripada memperluas skema ApsNet, karena saya dapat dengan mudah menangani perubahan di masa depan untuk AspNet Identity dan pada saat yang sama pemisahan membuatnya menjadi jelas bagi para programmer, bahwa "informasi pengguna kami sendiri" masuk dalam skema pengguna tertentu yang telah kami tentukan .


2
Saya gagal melihat pertanyaan apa pun di balasan saya. Saya tidak mengajukan satu pertanyaan pun! Alih-alih berbagi skenario di mana topik diskusi masuk akal.
freilebt

0

Huh, menghabiskan cukup banyak waktu pada masalah dengan konteks DB yang terpisah untuk setiap skema DB, berharap itu akan membantu orang lain ...

Saya baru-baru ini mulai mengerjakan proyek yang memiliki satu database dengan 3 skema (pendekatan pertama DB), salah satunya untuk manajemen pengguna. Ada konteks DB scaffolded dari masing-masing skema terpisah. Tentu saja, pengguna juga terkait dengan skema lain, misalnya. skema KB memiliki Topik tabel, yang telah "dibuat oleh", "terakhir dimodifikasi oleh" dll. FK untuk skema identitas, pengguna tabel.

Objek-objek ini dimuat secara terpisah dalam C #, pertama, topik dimuat dari 1 konteks, kemudian pengguna dimuat melalui ID pengguna dari konteks db lainnya - tidak baik, harus memperbaikinya! (mirip dengan menggunakan beberapa dbcontext dalam database yang sama dengan EF 6 )

Pertama, saya mencoba menambahkan instruksi FK yang hilang dari skema identitas ke skema KB, ke EF modelBuilder dalam konteks KB DB. Sama seperti jika hanya ada 1 konteks, tapi saya pisahkan menjadi 2.

modelBuilder.Entity<Topic>(entity =>
{
  entity.HasOne(d => d.Creator)
    .WithMany(p => p.TopicCreator)
    .HasForeignKey(d => d.CreatorId)
    .HasConstraintName("fk_topic_app_users");

Itu tidak berhasil, karena konteks kb db tidak memiliki informasi tentang objek pengguna, postgres kembali kesalahan relation "AppUsers" does not exist. Pernyataan pilih tidak memiliki informasi yang tepat tentang skema, nama bidang dll.

Saya hampir menyerah, tetapi kemudian saya perhatikan saklar "-d" saat berlari dotnet ef dbcontext scaffold. Ini singkat untuk -data-anotasi - Gunakan atribut untuk mengkonfigurasi model (jika memungkinkan). Jika dihilangkan, hanya API yang fasih yang digunakan. Dengan saklar ini ditentukan, properti objek didefinisikan bukan dalam konteks db OnModelCreating(), melainkan pada objek itu sendiri, dengan atribut.

Dengan cara ini, EF mendapatkan informasi yang cukup untuk menghasilkan pernyataan SQL yang tepat dengan nama dan skema bidang yang tepat.

TL; DR: konteks DB yang terpisah tidak menangani hubungan (FK) di antara mereka dengan baik, setiap konteks hanya memiliki informasi tentang entitasnya sendiri. Saat menentukan "-data-anotasi" aktifkandotnet ef dbcontext scaffold , informasi ini tidak disimpan dalam setiap konteks yang terpisah, tetapi pada objek DB sendiri.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.