Fitur baru di EF Core 2.1

Selain banyak perbaikan bug dan peningkatan fungsional dan performa kecil, EF Core 2.1 mencakup beberapa fitur baru yang menarik:

Pemuatan lambat

EF Core sekarang berisi blok penyusun yang diperlukan bagi siapa saja untuk menulis kelas entitas yang dapat memuat properti navigasi mereka sesuai permintaan. Kami juga telah membuat paket baru, Microsoft.EntityFrameworkCore.Proxies, yang memanfaatkan blok bangunan tersebut untuk menghasilkan kelas proksi pemuatan malas berdasarkan kelas entitas yang dimodifikasi minimal (misalnya, kelas dengan properti navigasi virtual).

Baca bagian tentang pemuatan malas untuk informasi selengkapnya tentang topik ini.

Parameter dalam konstruktor entitas

Sebagai salah satu blok penyusun yang diperlukan untuk pemuatan malas, kami mengaktifkan pembuatan entitas yang mengambil parameter dalam konstruktornya. Anda dapat menggunakan parameter untuk menyuntikkan nilai properti, delegasi pemuatan malas, dan layanan.

Baca bagian tentang konstruktor entitas dengan parameter untuk informasi selengkapnya tentang topik ini.

Konversi nilai

Hingga saat ini, EF Core hanya dapat memetakan properti jenis yang didukung secara asli oleh penyedia database yang mendasar. Nilai disalin bolak-balik antara kolom dan properti tanpa transformasi apa pun. Dimulai dengan EF Core 2.1, konversi nilai dapat diterapkan untuk mengubah nilai yang diperoleh dari kolom sebelum diterapkan ke properti, dan sebaliknya. Kami memiliki sejumlah konversi yang dapat diterapkan oleh konvensi seperlunya, serta API konfigurasi eksplisit yang memungkinkan mendaftarkan konversi kustom antara kolom dan properti. Beberapa aplikasi fitur ini adalah:

  • Menyimpan enum sebagai string
  • Memetakan bilangan bulat yang tidak ditandatangani dengan SQL Server
  • Enkripsi otomatis dan dekripsi nilai properti

Baca bagian tentang konversi nilai untuk informasi selengkapnya tentang topik ini.

Terjemahan LINQ GroupBy

Sebelum versi 2.1, di EF Core operator GroupBy LINQ akan selalu dievaluasi dalam memori. Kami sekarang mendukung penerjemahan ke klausul SQL GROUP BY dalam kasus yang paling umum.

Contoh ini memperlihatkan kueri dengan GroupBy yang digunakan untuk menghitung berbagai fungsi agregat:

var query = context.Orders
    .GroupBy(o => new { o.CustomerId, o.EmployeeId })
    .Select(g => new
        {
          g.Key.CustomerId,
          g.Key.EmployeeId,
          Sum = g.Sum(o => o.Amount),
          Min = g.Min(o => o.Amount),
          Max = g.Max(o => o.Amount),
          Avg = g.Average(o => o.Amount)
        });

Terjemahan SQL yang sesuai terlihat seperti ini:

SELECT [o].[CustomerId], [o].[EmployeeId],
    SUM([o].[Amount]), MIN([o].[Amount]), MAX([o].[Amount]), AVG([o].[Amount])
FROM [Orders] AS [o]
GROUP BY [o].[CustomerId], [o].[EmployeeId];

Data Seeding

Dengan rilis baru, anda dapat menyediakan data awal untuk mengisi database. Tidak seperti di EF6, data seeding dikaitkan dengan jenis entitas sebagai bagian dari konfigurasi model. Kemudian migrasi EF Core dapat secara otomatis menghitung operasi penyisipan, pembaruan, atau penghapusan apa yang perlu diterapkan saat meningkatkan database ke versi model baru.

Sebagai contoh, Anda dapat menggunakan ini untuk mengonfigurasi data benih untuk Posting di OnModelCreating:

modelBuilder.Entity<Post>().HasData(new Post{ Id = 1, Text = "Hello World!" });

Baca bagian tentang penyemaian data untuk informasi selengkapnya tentang topik ini.

Jenis kueri

Model EF Core sekarang dapat menyertakan jenis kueri. Tidak seperti jenis entitas, jenis kueri tidak memiliki kunci yang ditentukan dan tidak dapat disisipkan, dihapus, atau diperbarui (yaitu, mereka baca-saja), tetapi dapat dikembalikan langsung oleh kueri. Beberapa skenario penggunaan untuk jenis kueri adalah:

  • Pemetaan ke tampilan tanpa kunci primer
  • Pemetaan ke tabel tanpa kunci primer
  • Pemetaan ke kueri yang ditentukan dalam model
  • Berfungsi sebagai jenis pengembalian untuk FromSql() kueri

Baca bagian tentang jenis kueri untuk informasi selengkapnya tentang topik ini.

Sertakan untuk jenis turunan

Sekarang dimungkinkan untuk menentukan properti navigasi hanya didefinisikan pada jenis turunan saat menulis ekspresi untuk metode .Include Untuk versi yang sangat diketik Include, kami mendukung penggunaan cast eksplisit atau as operator. Kami juga sekarang mendukung referensi nama properti navigasi yang ditentukan pada jenis turunan Includedalam versi string :

var option1 = context.People.Include(p => ((Student)p).School);
var option2 = context.People.Include(p => (p as Student).School);
var option3 = context.People.Include("School");

Baca bagian tentang Sertakan dengan jenis turunan untuk informasi selengkapnya tentang topik ini.

Dukungan System.Transactions

Kami telah menambahkan kemampuan untuk bekerja dengan fitur System.Transactions seperti TransactionScope. Ini akan berfungsi pada .NET Framework dan .NET Core saat menggunakan penyedia database yang mendukungnya.

Baca bagian tentang System.Transactions untuk informasi selengkapnya tentang topik ini.

Urutan kolom yang lebih baik dalam migrasi awal

Berdasarkan umpan balik pelanggan, kami telah memperbarui migrasi untuk awalnya menghasilkan kolom untuk tabel dalam urutan yang sama dengan properti yang dideklarasikan dalam kelas. Perhatikan bahwa EF Core tidak dapat mengubah urutan saat anggota baru ditambahkan setelah pembuatan tabel awal.

Pengoptimalan subkueri berkorelasi

Kami telah meningkatkan terjemahan kueri kami untuk menghindari eksekusi kueri SQL "N + 1" dalam banyak skenario umum di mana penggunaan properti navigasi dalam proyeksi menyebabkan bergabungnya data dari kueri akar dengan data dari subkueri yang berkorelasi. Pengoptimalan memerlukan buffer hasil dari subkueri, dan kami mengharuskan Anda mengubah kueri untuk memilih perilaku baru.

Sebagai contoh, kueri berikut biasanya diterjemahkan ke dalam satu kueri untuk Pelanggan, ditambah N (di mana "N" adalah jumlah pelanggan yang dikembalikan) kueri terpisah untuk Pesanan:

var query = context.Customers.Select(
    c => c.Orders.Where(o => o.Amount  > 100).Select(o => o.Amount));

Dengan menyertakan ToList() di tempat yang tepat, Anda menunjukkan bahwa buffering sesuai untuk Pesanan, yang memungkinkan pengoptimalan:

var query = context.Customers.Select(
    c => c.Orders.Where(o => o.Amount  > 100).Select(o => o.Amount).ToList());

Perhatikan bahwa kueri ini hanya akan diterjemahkan ke dua kueri SQL: Satu untuk Pelanggan dan kueri berikutnya untuk Pesanan.

Atribut [Dimiliki]

Sekarang dimungkinkan untuk mengonfigurasi jenis entitas yang dimiliki hanya dengan membuat anotasi jenis dengan [Owned] dan kemudian memastikan entitas pemilik ditambahkan ke model:

[Owned]
public class StreetAddress
{
    public string Street { get; set; }
    public string City { get; set; }
}

public class Order
{
    public int Id { get; set; }
    public StreetAddress ShippingAddress { get; set; }
}

Alat baris perintah dotnet-ef disertakan dalam .NET Core SDK

Perintah dotnet-ef sekarang menjadi bagian dari .NET Core SDK, oleh karena itu tidak perlu lagi menggunakan DotNetCliToolReference dalam proyek untuk dapat menggunakan migrasi atau untuk membuat perancah DbContext dari database yang ada.

Lihat bagian tentang menginstal alat untuk detail selengkapnya tentang cara mengaktifkan alat baris perintah untuk versi .NET Core SDK dan EF Core yang berbeda.

Paket Microsoft.EntityFrameworkCore.Abstractions

Paket baru berisi atribut dan antarmuka yang dapat Anda gunakan dalam proyek Anda untuk menerangi fitur EF Core tanpa mengambil dependensi pada EF Core secara keseluruhan. Misalnya, atribut [Milik] dan antarmuka ILazyLoader terletak di sini.

Peristiwa perubahan status

Peristiwa Baru Tracked dan StateChanged aktif ChangeTracker dapat digunakan untuk menulis logika yang bereaksi terhadap entitas yang memasuki DbContext atau mengubah statusnya.

Penganalisis parameter SQL mentah

Penganalisis kode baru disertakan dengan EF Core yang mendeteksi kemungkinan penggunaan API SQL mentah kami yang berpotensi tidak aman, seperti FromSql atau ExecuteSqlCommand. Misalnya, untuk kueri berikut, Anda akan melihat peringatan karena minAge tidak diparameterkan:

var sql = $"SELECT * FROM People WHERE Age > {minAge}";
var query = context.People.FromSql(sql);

Kompatibilitas penyedia database

Disarankan agar Anda menggunakan EF Core 2.1 dengan penyedia yang telah diperbarui atau setidaknya diuji untuk bekerja dengan EF Core 2.1.

Tip

Jika Anda menemukan ketidaksesuaian tak terduga atau masalah apa pun di fitur baru, atau jika Anda memiliki umpan balik tentang fitur tersebut, laporkan menggunakan pelacak masalah kami.