Tablo BölmeTable Splitting

EF Core iki veya daha fazla varlığı tek bir satıra eşlemeye izin verir.EF Core allows to map two or more entities to a single row. Bu, tablo bölme veya _tablo paylaşma_olarak adlandırılır.This is called table splitting or table sharing.

YapılandırmaConfiguration

Varlık türlerinin tablo bölmeyi kullanmak için aynı tabloya eşlenmesi gerekir, birincil anahtarların aynı sütunlara ve bir varlık türünün birincil anahtarı ile aynı tabloda diğeri arasında yapılandırılmış en az bir ilişkiye sahip olması gerekir.To use table splitting the entity types need to be mapped to the same table, have the primary keys mapped to the same columns and at least one relationship configured between the primary key of one entity type and another in the same table.

Tablo bölme için yaygın bir senaryo, daha fazla performans veya kapsülleme için tablodaki sütunların yalnızca bir alt kümesini kullanmaktır.A common scenario for table splitting is using only a subset of the columns in the table for greater performance or encapsulation.

Bu örnekte Order , bir alt kümesini temsil eder DetailedOrder .In this example Order represents a subset of DetailedOrder.

public class Order
{
    public int Id { get; set; }
    public OrderStatus? Status { get; set; }
    public DetailedOrder DetailedOrder { get; set; }
}
public class DetailedOrder
{
    public int Id { get; set; }
    public OrderStatus? Status { get; set; }
    public string BillingAddress { get; set; }
    public string ShippingAddress { get; set; }
    public byte[] Version { get; set; }
}

Gereken yapılandırmaya ek olarak Property(o => o.Status).HasColumnName("Status") , ile aynı sütuna eşleme çağrısı yaptık DetailedOrder.Status Order.Status .In addition to the required configuration we call Property(o => o.Status).HasColumnName("Status") to map DetailedOrder.Status to the same column as Order.Status.

modelBuilder.Entity<DetailedOrder>(dob =>
{
    dob.ToTable("Orders");
    dob.Property(o => o.Status).HasColumnName("Status");
});

modelBuilder.Entity<Order>(ob =>
{
    ob.ToTable("Orders");
    ob.Property(o => o.Status).HasColumnName("Status");
    ob.HasOne(o => o.DetailedOrder).WithOne()
        .HasForeignKey<DetailedOrder>(o => o.Id);
});

İpucu

Daha fazla bağlam için bkz. tam örnek proje .See the full sample project for more context.

KullanımUsage

Tablo bölme kullanarak varlıkları kaydetme ve sorgulama, diğer varlıklarla aynı şekilde yapılır:Saving and querying entities using table splitting is done in the same way as other entities:

using (var context = new TableSplittingContext())
{
    context.Database.EnsureDeleted();
    context.Database.EnsureCreated();

    context.Add(new Order
    {
        Status = OrderStatus.Pending,
        DetailedOrder = new DetailedOrder
        {
            Status = OrderStatus.Pending,
            ShippingAddress = "221 B Baker St, London",
            BillingAddress = "11 Wall Street, New York"
        }
    });

    context.SaveChanges();
}

using (var context = new TableSplittingContext())
{
    var pendingCount = context.Orders.Count(o => o.Status == OrderStatus.Pending);
    Console.WriteLine($"Current number of pending orders: {pendingCount}");
}

using (var context = new TableSplittingContext())
{
    var order = context.DetailedOrders.First(o => o.Status == OrderStatus.Pending);
    Console.WriteLine($"First pending order will ship to: {order.ShippingAddress}");
}

İsteğe bağlı bağımlı varlıkOptional dependent entity

Not

Bu özellik EF Core 3,0 ' de tanıtılmıştı.This feature was introduced in EF Core 3.0.

Bağımlı bir varlık tarafından kullanılan tüm sütunlar NULL veritabanında ise, sorgulanan zaman bir örnek oluşturulmaz.If all of the columns used by a dependent entity are NULL in the database, then no instance for it will be created when queried. Bu, Principal 'ın ilişki özelliğinin null olacağı, isteğe bağlı bir bağımlı varlığın modellemesini sağlar.This allows modeling an optional dependent entity, where the relationship property on the principal would be null. Bunun aynı zamanda, bağımlı olduğu tüm özellikler isteğe bağlıdır ve olarak ayarlandıysa null , beklenmeyebilir.Note that this would also happen if all of the dependent's properties are optional and set to null, which might not be expected.

Eşzamanlılık belirteçleriConcurrency tokens

Bir tabloyu paylaşan varlık türlerinden herhangi birinde eşzamanlılık belirteci varsa, bu, diğer tüm varlık türlerine de dahil olmalıdır.If any of the entity types sharing a table has a concurrency token then it must be included in all other entity types as well. Aynı tabloyla eşlenmiş varlıkların yalnızca biri güncelleştirildiği zaman eski bir eşzamanlılık belirteci değerinden kaçınmak için bu gereklidir.This is necessary in order to avoid a stale concurrency token value when only one of the entities mapped to the same table is updated.

Eşzamanlılık belirtecini, tüketim kodunda açığa çıkarmamak için bir gölge özelliğiolarak oluştur mümkündür:To avoid exposing the concurrency token to the consuming code, it's possible the create one as a shadow property:

modelBuilder.Entity<Order>()
    .Property<byte[]>("Version").IsRowVersion().HasColumnName("Version");

modelBuilder.Entity<DetailedOrder>()
    .Property(o => o.Version).IsRowVersion().HasColumnName("Version");