2011-08-22 29 views
17

Tôi có một hệ thống phân cấp lớp mà tôi muốn ánh xạ trên một số bảng bằng cách sử dụng Entity Framework 4.1 Code First. Nó giống như bàn mỗi loại (TPT) nhưng tôi cũng muốn một cột phân biệt đối xử.Tôi có thể chỉ định một cột phân biệt đối xử với ánh xạ bảng cho mỗi loại không?

Hàng giáo phẩm trông giống như sau:

public class Event 
{ 
    public Guid Id { get; set; } 
    public string Code { get; set; } // discriminator 
    public DateTime Date { get; set; } 
} 

public class Party : Event 
{ 
    public int AttendeeCount { get; set; } 
} 

public class BirthdayParty : Party 
{ 
    public int Age { get; set; } 
} 

public class WeddingParty : Party 
{ 
    public string Surname { get; set; } 
} 

Đây là một ví dụ khá yếu nhưng tôi hy vọng nó có ý nghĩa. Sẽ có một bảng "Sự kiện", một bảng "Các bên" và một bảng cho từng loại bữa tiệc. Tuy nhiên, cột phân biệt đối xử ("Code") sẽ có giá trị đã biết cho mỗi loại sự kiện, như "BIRTH" cho các bữa tiệc sinh nhật hoặc "WEDDING" cho tiệc cưới. Ý tưởng là nếu tôi chỉ truy vấn các bữa tiệc sinh nhật vào một ngày cụ thể, EF sẽ biết thêm Code = 'BIRTH' vào truy vấn của tôi thay vì thực hiện một loạt các UNION và JOIN để tìm ra những hàng cần thiết.

tôi lập bản đồ lớp cấp thấp nhất của tôi như thế này:

var bd = modelBuilder.Entity<BirthdayParty>(); 
bd.ToTable("BirthdayParties"); 
bd.Property(p => p.Age).HasColumnName("BirthdayAge"); 

bây giờ tôi cần phải xác định giá trị phân biệt trong đó bằng cách nào đó. Tôi đã thử điều này:

modelBuilder.Entity<Event>().Map<BirthdayParty>(cfg => 
    { 
     cfg.Requires("Code").HasValue("BIRTH"); 
    }); 

... nhưng điều đó phàn nàn rằng tôi chưa chỉ định tên bảng trong cuộc gọi đến Map. Vì vậy, tôi đã cố gắng di chuyển ToTable gọi vào đó:

var bd = modelBuilder.Entity<BirthdayParty>(); 
bd.Property(p => p.Age).HasColumnName("BirthdayAge"); 

modelBuilder.Entity<Event>().Map<BirthdayParty>(cfg => 
    { 
     cfg.Requires("Code").HasValue("BIRTH"); 
     cfg.ToTable("BirthdayParties"); 
    }); 

... và bây giờ nó nghĩ rằng tôi muốn có một "Mã" cột trong "BirthdayParties" bảng, mà không phải là chính xác. Tôi đã nói với nó rằng cột "Mã" nằm trong bảng "Sự kiện".

Điều này có thể thực hiện được không? Tôi có thể kết hợp việc sử dụng cột phân biệt đối xử với ánh xạ bảng cho mỗi loại không?

Trả lời

8

Rất tiếc, điều này không được hỗ trợ. Cột phân biệt đối xử chỉ có thể được sử dụng trong TPH. TPT khác các loại thực thể bằng các bảng được ánh xạ và nó luôn tạo ra các truy vấn khủng khiếp đó. Nó có thể là tính năng tốt đẹp vì vậy có lẽ gợi ý trên Data UserVoice sẽ làm cho nó thực hiện một ngày.

Cập nhật

Đã có một gợi ý về giọng nói người dùng cho tựa đề "Discriminator column support in TPT inheritance" này.

0

Tôi đã ghi đè lên SaveChanges để thực hiện điều gì đó tương tự. Tôi chỉ cần thêm một thuộc tính vào lớp trừu tượng có tên là Descriminator và thiết lập nó dựa trên Tên Lớp Bê tông bất cứ khi nào một cái gì đó mới được thêm vào.

public class MyContext : DbContext 
{   
    public override int SaveChanges() 
    { 
     foreach (var item in ChangeTracker.Entries().Where(x=>x.Entity is MyAbstractClass && x.State == EntityState.Added)) 
     { 
      ((MyAbstractClass)item.Entity).Descriminator = item.Entity.GetType().Name; 
     } 
     return base.SaveChanges(); 
    } 
} 
Các vấn đề liên quan