Bagikan melalui


Jenis Entitas

Menyertakan DbSet jenis pada konteks Anda berarti bahwa itu termasuk dalam model EF Core; kami biasanya merujuk ke jenis seperti itu sebagai entitas. EF Core dapat membaca dan menulis instans entitas dari/ke database, dan jika Anda menggunakan database relasional, EF Core dapat membuat tabel untuk entitas Anda melalui migrasi.

Menyertakan jenis dalam model

Menurut konvensi, jenis yang diekspos di properti DbSet pada konteks Anda disertakan dalam model sebagai entitas. Jenis entitas yang ditentukan dalam OnModelCreating metode juga disertakan, seperti jenis apa pun yang ditemukan dengan menjelajahi properti navigasi jenis entitas lain yang ditemukan secara rekursif.

Dalam sampel kode di bawah ini, semua jenis disertakan:

  • Blog disertakan karena diekspos dalam properti DbSet pada konteks.
  • Post disertakan karena ditemukan melalui Blog.Posts properti navigasi.
  • AuditEntry karena ditentukan dalam OnModelCreating.
internal class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<AuditEntry>();
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public Blog Blog { get; set; }
}

public class AuditEntry
{
    public int AuditEntryId { get; set; }
    public string Username { get; set; }
    public string Action { get; set; }
}

Mengecualikan jenis dari model

Jika Anda tidak ingin jenis disertakan dalam model, Anda dapat mengecualikannya:

[NotMapped]
public class BlogMetadata
{
    public DateTime LoadedFromDatabase { get; set; }
}

Mengecualikan dari migrasi

Terkadang berguna untuk memiliki jenis entitas yang sama yang dipetakan dalam beberapa DbContext jenis. Ini terutama berlaku saat menggunakan konteks terikat, yang umumnya memiliki jenis yang berbeda DbContext untuk setiap konteks terikat.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<IdentityUser>()
        .ToTable("AspNetUsers", t => t.ExcludeFromMigrations());
}

Dengan migrasi konfigurasi ini tidak akan membuat AspNetUsers tabel, tetapi IdentityUser masih disertakan dalam model dan dapat digunakan secara normal.

Jika Anda perlu mulai mengelola tabel menggunakan migrasi lagi, maka migrasi baru harus dibuat di mana AspNetUsers tidak dikecualikan. Migrasi berikutnya sekarang akan berisi perubahan apa pun yang dilakukan pada tabel.

Nama tabel

Menurut konvensi, setiap jenis entitas akan disiapkan untuk memetakan ke tabel database dengan nama yang sama dengan properti DbSet yang mengekspos entitas. Jika tidak ada DbSet untuk entitas yang diberikan, nama kelas akan digunakan.

Anda dapat mengonfigurasi nama tabel secara manual:

[Table("blogs")]
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}

Skema tabel

Saat menggunakan database relasional, tabel dibuat berdasarkan konvensi yang dibuat dalam skema default database Anda. Misalnya, Microsoft SQL Server akan menggunakan dbo skema (SQLite tidak mendukung skema).

Anda dapat mengonfigurasi tabel yang akan dibuat dalam skema tertentu sebagai berikut:

[Table("blogs", Schema = "blogging")]
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}

Daripada menentukan skema untuk setiap tabel, Anda juga dapat menentukan skema default di tingkat model dengan API yang fasih:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasDefaultSchema("blogging");
}

Perhatikan bahwa mengatur skema default juga akan memengaruhi objek database lainnya, seperti urutan.

Menampilkan pemetaan

Jenis entitas dapat dipetakan ke tampilan database menggunakan FLUENT API.

Catatan

EF akan mengasumsikan bahwa tampilan yang dirujuk sudah ada dalam database, itu tidak akan membuatnya secara otomatis dalam migrasi.

modelBuilder.Entity<Blog>()
    .ToView("blogsView", schema: "blogging");

Pemetaan ke tampilan akan menghapus pemetaan tabel default, tetapi jenis entitas juga dapat dipetakan ke tabel secara eksplisit. Dalam hal ini pemetaan kueri akan digunakan untuk kueri dan pemetaan tabel akan digunakan untuk pembaruan.

Tip

Untuk menguji jenis entitas tanpa kunci yang dipetakan ke tampilan menggunakan penyedia dalam memori, petakan ke kueri melalui ToInMemoryQuery. Lihat dokumen penyedia dalam memori untuk informasi selengkapnya.

Pemetaan fungsi bernilai tabel

Dimungkinkan untuk memetakan jenis entitas ke fungsi bernilai tabel (TVF) alih-alih tabel dalam database. Untuk mengilustrasikan ini, mari kita tentukan entitas lain yang mewakili blog dengan beberapa postingan. Dalam contoh, entitas tidak memiliki kunci, tetapi tidak harus.

public class BlogWithMultiplePosts
{
    public string Url { get; set; }
    public int PostCount { get; set; }
}

Selanjutnya, buat fungsi bernilai tabel berikut dalam database, yang hanya mengembalikan blog dengan beberapa postingan serta jumlah postingan yang terkait dengan masing-masing blog ini:

CREATE FUNCTION dbo.BlogsWithMultiplePosts()
RETURNS TABLE
AS
RETURN
(
    SELECT b.Url, COUNT(p.BlogId) AS PostCount
    FROM Blogs AS b
    JOIN Posts AS p ON b.BlogId = p.BlogId
    GROUP BY b.BlogId, b.Url
    HAVING COUNT(p.BlogId) > 1
)

Sekarang, entitas BlogWithMultiplePosts dapat dipetakan ke fungsi ini dengan cara berikut:

modelBuilder.Entity<BlogWithMultiplePosts>().HasNoKey().ToFunction("BlogsWithMultiplePosts");

Catatan

Untuk memetakan entitas ke fungsi bernilai tabel, fungsi harus tanpa parameter.

Secara konvensional, properti entitas akan dipetakan ke kolom yang cocok yang dikembalikan oleh TVF. Jika kolom yang dikembalikan oleh TVF memiliki nama yang berbeda dari properti entitas, maka kolom entitas dapat dikonfigurasi menggunakan HasColumnName metode, sama seperti saat memetakan ke tabel biasa.

Saat jenis entitas dipetakan ke fungsi bernilai tabel, kueri:

var query = from b in context.Set<BlogWithMultiplePosts>()
            where b.PostCount > 3
            select new { b.Url, b.PostCount };

Menghasilkan SQL berikut:

SELECT [b].[Url], [b].[PostCount]
FROM [dbo].[BlogsWithMultiplePosts]() AS [b]
WHERE [b].[PostCount] > 3

Komentar tabel

Anda bisa mengatur komentar teks arbitrer yang diatur pada tabel database, memungkinkan Anda mendokumentasikan skema Anda dalam database:

[Comment("Blogs managed on the website")]
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}

Jenis entitas jenis bersama

Jenis entitas yang menggunakan jenis CLR yang sama dikenal sebagai jenis entitas jenis bersama. Jenis entitas ini perlu dikonfigurasi dengan nama unik, yang harus disediakan setiap kali jenis entitas jenis bersama digunakan, selain jenis CLR. Ini berarti bahwa properti yang DbSet sesuai harus diimplementasikan menggunakan Set panggilan.

internal class MyContext : DbContext
{
    public DbSet<Dictionary<string, object>> Blogs => Set<Dictionary<string, object>>("Blog");

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.SharedTypeEntity<Dictionary<string, object>>(
            "Blog", bb =>
            {
                bb.Property<int>("BlogId");
                bb.Property<string>("Url");
                bb.Property<DateTime>("LastUpdated");
            });
    }
}