Properti Bayangan dan Pengindeks
Properti bayangan adalah properti yang tidak ditentukan di kelas entitas .NET Anda tetapi didefinisikan untuk jenis entitas tersebut dalam model EF Core. Nilai dan status properti ini dipertahankan murni di Pelacak Perubahan. Properti bayangan berguna ketika ada data dalam database yang seharusnya tidak diekspos pada jenis entitas yang dipetakan.
Properti pengindeks adalah properti jenis entitas, yang didukung oleh pengindeks di kelas entitas .NET. Mereka dapat diakses menggunakan pengindeks pada instans kelas .NET. Ini juga memungkinkan Anda untuk menambahkan properti tambahan ke jenis entitas tanpa mengubah kelas CLR.
Properti bayangan kunci asing
Properti bayangan paling sering digunakan untuk properti kunci asing, di mana properti tersebut ditambahkan ke model berdasarkan konvensi ketika tidak ada properti kunci asing yang ditemukan oleh konvensi atau dikonfigurasi secara eksplisit. Hubungan diwakili oleh properti navigasi, tetapi dalam database diberlakukan oleh batasan kunci asing, dan nilai untuk kolom kunci asing disimpan di properti bayangan yang sesuai.
Properti akan diberi nama <navigation property name><principal key property name>
(navigasi pada entitas dependen, yang menunjuk ke entitas utama, digunakan untuk penamaan). Jika nama properti kunci utama dimulai dengan nama properti navigasi, maka namanya hanya akan .<principal key property name>
Jika tidak ada properti navigasi pada entitas dependen, maka nama jenis utama yang digabungkan dengan nama properti kunci utama atau alternatif digunakan di tempatnya <principal type name><principal key property name>
.
Misalnya, daftar kode berikut akan mengakibatkan BlogId
properti bayangan diperkenalkan ke Post
entitas:
internal class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
}
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; }
// Since there is no CLR property which holds the foreign
// key for this relationship, a shadow property is created.
public Blog Blog { get; set; }
}
Mengonfigurasi properti bayangan
Anda dapat menggunakan FLUENT API untuk mengonfigurasi properti bayangan. Setelah Anda memanggil string kelebihan beban Property<TProperty>(String), Anda dapat menautkan salah satu panggilan konfigurasi yang Anda lakukan untuk properti lain. Dalam sampel berikut, karena Blog
tidak memiliki properti CLR bernama LastUpdated
, properti bayangan dibuat:
internal class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property<DateTime>("LastUpdated");
}
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
Jika nama yang diberikan ke Property
metode cocok dengan nama properti yang ada (properti bayangan atau yang ditentukan pada kelas entitas), maka kode akan mengonfigurasi properti yang ada daripada memperkenalkan properti bayangan baru.
Mengakses properti bayangan
Nilai properti bayangan dapat diperoleh dan diubah melalui ChangeTracker
API:
context.Entry(myBlog).Property("LastUpdated").CurrentValue = DateTime.Now;
Properti bayangan dapat direferensikan dalam kueri LINQ melalui EF.Property
metode statis:
var blogs = context.Blogs
.OrderBy(b => EF.Property<DateTime>(b, "LastUpdated"));
Properti bayangan tidak dapat diakses setelah kueri tanpa pelacakan karena entitas yang dikembalikan tidak dilacak oleh pelacak perubahan.
Mengonfigurasi properti pengindeks
Anda dapat menggunakan FLUENT API untuk mengonfigurasi properti pengindeks. Setelah memanggil metode IndexerProperty
, Anda dapat menautkan salah satu panggilan konfigurasi yang Anda lakukan untuk properti lain. Dalam sampel berikut, Blog
memiliki pengindeks yang ditentukan dan akan digunakan untuk membuat properti pengindeks.
internal class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>().IndexerProperty<DateTime>("LastUpdated");
}
}
public class Blog
{
private readonly Dictionary<string, object> _data = new Dictionary<string, object>();
public int BlogId { get; set; }
public object this[string key]
{
get => _data[key];
set => _data[key] = value;
}
}
Jika nama yang diberikan ke IndexerProperty
metode cocok dengan nama properti pengindeks yang ada, maka kode akan mengonfigurasi properti yang ada. Jika jenis entitas memiliki properti, yang didukung oleh properti pada kelas entitas, maka pengecualian dilemparkan karena properti pengindeks hanya boleh diakses melalui pengindeks.
Properti pengindeks dapat direferensikan dalam kueri LINQ melalui metode statis seperti yang EF.Property
ditunjukkan di atas atau dengan menggunakan properti pengindeks CLR.
Jenis entitas tas properti
Jenis entitas yang hanya berisi properti pengindeks dikenal sebagai jenis entitas tas properti. Jenis entitas ini tidak memiliki properti bayangan, dan EF membuat properti pengindeks sebagai gantinya. Saat ini hanya Dictionary<string, object>
didukung sebagai jenis entitas tas properti. Ini harus dikonfigurasi sebagai jenis entitas jenis bersama dengan nama unik dan 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");
});
}
}
Jenis entitas tas properti dapat digunakan di mana pun jenis entitas normal digunakan, termasuk sebagai jenis entitas yang dimiliki. Namun, mereka memang memiliki batasan tertentu: