2013-09-04 35 views
9

Tôi đang cố gắng sử dụng hai thực thể khác nhau trên cùng một bảng. Mục đích của việc có hai thực thể là giới hạn số lượng thuộc tính trong một trong số chúng, bởi vì trên một trong các dạng chỉnh sửa, nó chỉ có thể thay đổi một vài thuộc tính. Vì vậy, để tránh phải có các thuộc tính không thể chỉnh sửa được ẩn để giữ nguyên giá trị của chúng, tôi nghĩ rằng việc có một thực thể riêng biệt chỉ với một phần thuộc tính sẽ là một ý tưởng hay.Làm thế nào để có nhiều thực thể ánh xạ với một bảng?

Vì vậy, tôi có một thực thể với tất cả các thuộc tính và một thuộc tính chỉ với một số thuộc tính. Vấn đề là tôi nhận được ngoại lệ này:

`Các loại thực thể 'ApplicationMapping' và 'ApplicationMappingFull' không thể chia sẻ bảng 'ApplicationMapping' vì họ không nằm trong cùng hệ thống phân cấp loại hoặc không có một giá trị với một khóa ngoại quan quan hệ với các khóa chính tương ứng giữa chúng.

Các lớp cấu hình thực thể giống như thế này:

class ApplicationMappingFullConfiguration : EntityTypeConfiguration<ApplicationMappingFull> 
{ 
    public ApplicationMappingFullConfiguration() 
    { 
    ToTable("ApplicationMapping"); 
    HasKey(p => p.Id); 
    } 
} 

class ApplicationMappingConfiguration : EntityTypeConfiguration<ApplicationMapping> 
{ 
    public ApplicationMappingConfiguration() 
    { 
    ToTable("ApplicationMapping"); 
    HasKey(p => p.Id); 
    } 
} 

Làm thế nào tôi có thể đạt được những gì tôi đang cố gắng để làm gì? Có cách nào tốt hơn/đơn giản hơn để làm điều đó?

Cảm ơn!

+0

'ApplicationMappingFull' có kế thừa từ' ApplicationMapping' không? Bạn có thể thêm mã cho các lớp này vào câu hỏi của bạn không? –

+0

@HenkMollema Không, không có sự kế thừa giữa các thực thể. Chúng là những thực thể riêng biệt, một thực thể có tất cả các trường từ bảng, cái kia chỉ có một vài trường. – Stian

+0

Chỉ cần sử dụng hai mô hình chế độ xem riêng biệt mà cả hai ánh xạ trở lại cùng một thực thể. – dotjoe

Trả lời

4

Tôi khuyên bạn nên có một thực thể duy nhất được ánh xạ tới bảng, nhưng tạo hai thực thể 'xem' chỉ chứa các thuộc tính mà biểu mẫu yêu cầu.

Các thực thể chế độ xem này có thể chứa các phương pháp để ánh xạ dữ liệu được nhập trở lại thực thể cơ bản.

+0

Cảm ơn, tôi sẽ đi theo phương pháp này. – Stian

+0

Bạn có thể muốn google cho mẫu MVVM (Model - View - View Model), vì đây là những gì bạn đang xem tại đây. – Paddy

-1

Câu hỏi của bạn có câu trả lời.

The entity types 'ApplicationMapping' and 'ApplicationMappingFull' cannot share table 'ApplicationMapping' 

Khi bạn ánh xạ một loại thực thể để bàn, bạn đang định nghĩa giản đồ cho bảng. Như bạn đã nói, bạn có một thực thể với tất cả các thuộc tính, và một với chỉ một số thuộc tính. Khi bạn ánh xạ một thực thể vào bảng, bạn cần ánh xạ tất cả các cột của bảng.

Vì vậy, trong một dòng, "Không thể".

Để đạt được giải pháp cho vấn đề của bạn, bạn có thể làm những gì Paddy đề xuất. Khác bạn có thể tạo một lớp cơ sở với các thuộc tính bắt buộc tối thiểu sau đó mở rộng lớp đó và thêm các thuộc tính còn lại. Trong khi truyền mô hình cho khung nhìn, chuyển đối tượng lớp cơ sở. Tuy nhiên bạn có thể sử dụng đối tượng lớp mở rộng trong khi tìm nạp bản ghi từ cơ sở dữ liệu.

3

Có vẻ như những gì bạn đang tìm kiếm là TPH (Bảng mỗi phân cấp). Đây là một mẫu thừa kế quan hệ trong đó một lớp và tất cả các lớp con của nó chia sẻ cùng một bảng và được hỗ trợ nguyên bản bởi Entity Framework. Trong thực tế, nếu tất cả những gì bạn làm là có một thực thể kế thừa từ một thực thể khác, thì Entity Framework triển khai mẫu này theo mặc định. Bạn không cần phải làm bất cứ điều gì đặc biệt cả. Tuy nhiên, có một điều kiện: vì các thuộc tính trong lớp cơ sở phải đủ để có thể lưu thành công hàng vào cơ sở dữ liệu, tất cả các thuộc tính lớp con của bạn phải là tùy chọn - ít nhất là trên một cấp cơ sở dữ liệu.Bạn luôn có thể thực thi một hoặc nhiều thuộc tính cần thiết thông qua giao diện người dùng giao diện người dùng.

CẬP NHẬT

Mở rộng trên nhận xét của tôi dưới đây, nếu tất cả các bạn đang tìm kiếm để làm là trả lại một tập hợp con của dữ liệu từ bảng, sau đó bạn đã có tất cả các công cụ bạn cần. Bạn không cần hai thực thể riêng biệt, chỉ một thực thể (trong trường hợp này là lớp ApplicationMappingFull) của bạn và sau đó bạn có thể sử dụng LINQ để chỉ trả về những cột bạn cần.

db.ApplicationMappingFulls.Select(m => new ApplicationMappingViewModel 
    { 
     SomeProperty = m.SomeProperty, 
     OtherProperty = m.OtherProperty 
    }); 

Đằng sau hậu trường, EF sẽ phát hành một truy vấn mà sẽ chỉ chọn các cột SomePropertyOtherProperty, bởi vì đó là tất cả những gì cần thiết. Mô hình khung nhìn của bạn sẽ không được kết nối với EF; nó chỉ là một lớp để giữ dữ liệu được trả về bởi EF.

+0

Hey, tôi đã cố gắng sử dụng thừa kế, nhưng bây giờ tôi nhận được một ngoại lệ nói rằng tôi cần một "Discriminator" cột. Tôi hiểu mục đích của cột này, nhưng không có sự khác biệt giữa lớp cơ sở và lớp phụ. Tôi chỉ muốn có thể trên một dịp lấy một hàng từ bảng và đại diện cho nó bằng một đối tượng chỉ với một vài cột, và vào một dịp khác có cùng hàng với tất cả các cột .. Dữ liệu giống nhau ở cả hai các dịp và tất cả các hàng trong bảng đều có cùng loại. – Stian

+0

Nếu bạn chỉ đang nói về việc muốn hiển thị một lượng thông tin ít hơn từ cơ sở dữ liệu của mình, bạn không nên đối phó với hai thực thể nào cả. Với LINQ bạn có thể chọn chỉ các cột bạn muốn, và EF sẽ thực sự phát hành ở cấp cơ sở dữ liệu. Sau đó, bạn có thể trả lại một đối tượng ẩn danh chỉ là các thuộc tính đó hoặc tốt hơn, ánh xạ nó tới một mô hình khung nhìn. –

+0

Được rồi, cảm ơn! – Stian

1

Một giải pháp thay thế khác là có một lớp lấy được từ lớp kia và ẩn hoặc nói cách khác là các trường mà bạn không muốn cho phép chỉnh sửa.

Như một ví dụ ...

class Full { 
    public string ValueA {get;set;} 
} 

class Limited : Full { 
    public new string ValueA {get; private set;} 
} 

Đây là thừa nhận không phải là giải pháp vĩ đại nhất, nhưng sự lựa chọn khác, bạn có thể sử dụng.

Các vấn đề liên quan