5

Tôi đang sử dụng cơ sở dữ liệu đầu tiên với Entity Framework 5. Chúng tôi có hai bảng (ồ ạt đơn giản):Làm thế nào để thay đổi Navigation Tên tài sản Into tên có ý nghĩa

  • Addresses
    • đường
    • Town (vv .)
  • Khách hàng
    • Tên
    • BillingAddress
    • DeliveryAddress
    • AltDeliveryAddress

Khi chúng ta sử dụng Visual Studio để nhập cơ sở dữ liệu vào EF ("Cập nhật mô hình từ cơ sở dữ liệu"), chúng tôi kết thúc với mã như thế này:

Customer myCustomer; 
var a = myCustomer.Address; 
var b = myCustomer.Address1; 
var c = myCustomer.Address2; 

Điều tôi muốn hiển nhiên là như sau:

var a = myCustomer.BillingAddress; 
var z = myCustomer.BillingAddress.Street; // etc. 

Tôi chỉ có thể chỉnh sửa mô hình trong trình thiết kế, thay đổi Thuộc tính điều hướng để cung cấp cho tôi tên chính xác. Tuy nhiên đây không phải là giải pháp khả thi vì chúng tôi xây dựng lại mô hình mỗi khi chúng tôi thực hiện các thay đổi đối với cơ sở dữ liệu.

Một lựa chọn Tôi đã thử đang tạo ra một lớp học phần như thế này (mã sao chép từ MyModel.Designer.cs hiện chỉ với tên thuộc tính thay đổi):

public partial class Customer : EntityObject 
{ 
    [EdmRelationshipNavigationPropertyAttribute("MyModel", "FK_Customers_Addresses_BillingAddress", "Address")] 
    public Address BillingAddress 
    { 
     get { 
      return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<LookupItem>("MyModel.FK_Customers_Addresses_BillingAddress", "Address").Value; 
     } 
     set { 
      ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<LookupItem>("MyModel.FK_Customers_Addresses_BillingAddress", "Address").Value = value; 
     } 
    } 
} 

Tuy nhiên khi tôi chạy này, tôi nhận được lỗi sau:

The number of members in the conceptual type 'MyModel.Customer' does not match with the number of members on the object side type 'MyNamespace.DataModel.Customer'. Make sure the number of members are the same.

Tôi đã thử sử dụng thuộc tính [NotMapped()], nhưng điều đó không tạo ra bất kỳ sự khác biệt nào. Nếu tôi loại bỏ các [EdmRelationshipNavigationPropertyAttribute ...] thuộc tính thì LINQ phàn nàn với các lỗi sau:

The specified type member 'BillingAddress' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.

Có cách nào khác để đạt được tên có ý nghĩa trong Customers phản đối?

Dưới đây là những gì tôi muốn ở cuối:

var j = myCustomer.BillingAddress; 
var k = myCustomer.BillingAddress.Street; 
var l = myCustomer.BillingAddress.Town; // etc. 

Trả lời

2

Bạn có thể thêm các thuộc tính để partial class của bạn sẽ được accessors để tính Address1, Address2, vv

Ví dụ:

public partial class Customer : EntityObject 
{ 
    public Address BillingAddress 
    { 
     get 
     { 
      return this.Address; 
     } 
     set 
     { 
       this.Address = value; 
     } 
    } 
} 

Cập nhật: Nó sẽ không làm việc với LINQ to Entities. Tôi e rằng đây là hạn chế của phương pháp tiếp cận cơ sở dữ liệu đầu tiên. Đây là một trong những nguyên nhân khiến chúng tôi sử dụng mã EF đầu tiên. Trong Code First, bạn có toàn quyền kiểm soát ánh xạ thực thể.(Mã đầu tiên có nghĩa là ánh xạ trong mã, nó không có nghĩa là db của bạn sẽ được tạo ra từ mã này nếu bạn không muốn nó).

+0

Điều đó có tác dụng nếu bạn có thể chắc chắn về ánh xạ giữa tên được tạo của EF và tên cơ sở dữ liệu thực. tức là nếu .Address2 luôn là AltDeliveryAddress thì ok, nhưng có vẻ như không an toàn lắm. – andrewpm

+0

Trên thực tế không, điều đó không hoạt động khi tôi cố gắng sử dụng nó trong LINQ. Đây là mã của tôi: var clientsInSeattle = cs.Where (c => c.DeliveryAddress.Town == "Seattle"); Tôi nhận được lỗi này: Thành viên loại được chỉ định 'DeliveryAddress' không được hỗ trợ trong LINQ to Entities. Chỉ các trình khởi tạo, thành viên thực thể và thuộc tính điều hướng thực thể mới được hỗ trợ. – andrewpm

+0

Vâng, đó là sự thật ... Tôi e rằng đây là hạn chế của phương pháp tiếp cận cơ sở dữ liệu đầu tiên. Đây là một trong những nguyên nhân khiến chúng tôi sử dụng mã EF đầu tiên. Trong Code First, bạn có toàn quyền kiểm soát ánh xạ thực thể. (Mã đầu tiên có nghĩa là ánh xạ trong mã, nó không có nghĩa là db của bạn sẽ được tạo ra từ mã này nếu bạn không muốn nó). –

3

Bạn có lẽ không cần phải lo lắng về việc này. Sau khi thay đổi tên thuộc tính trong thiết kế mô hình EF sẽ nhớ tên tùy chỉnh. Nó sẽ không bị ghi đè bởi các bản cập nhật tiếp theo.

+2

Vâng, nó chỉ hoạt động miễn là bạn không loại bỏ các thực thể và readd nó vào mô hình của bạn những gì có thể xảy ra nếu bạn muốn syncronize mô hình của bạn với cơ sở dữ liệu. f.e. việc xóa một cột trong cơ sở dữ liệu không giống nhau trong mô hình của bạn khi làm mới – KroaX

+2

Thật không may là nhà thiết kế EF không đáng tin cậy. Thông thường, chúng tôi chỉ xóa toàn bộ mô hình và tạo lại mô hình đó, vì cố gắng thực hiện cập nhật sẽ phá vỡ nó. Do đó, tùy chọn này không có sẵn cho chúng tôi. – andrewpm

+0

nếu tôi thực hiện thay đổi đối với mô hình, liệu nó có thay đổi tương ứng với các lớp cơ sở dữ liệu và mã hiện có không? ... Tôi thật sự muốn điều đó. –

0

Tôi biết điều này hơi cũ, nhưng có vẻ cách dễ nhất/tốt nhất để xử lý tình huống này là tận dụng công cụ điện năng EF5 "mã kỹ sư đảo ngược đầu tiên".

http://msdn.microsoft.com/en-us/data/jj200620

Nó cung cấp cho bạn tất cả những ưu điểm của mã ánh xạ đầu tiên với sự đơn giản/tiện lợi của cơ sở dữ liệu tạo đối tượng đầu tiên.

0

có một giải pháp được mô tả ở đây:

Improve navigation property names when reverse engineering a database

Bạn có thể bao gồm các mẫu thế hệ mã vào dự án của bạn (* file tt.). Sửa đổi chúng như được mô tả trên liên kết. Mẫu có tại đây: https://github.com/markuspeter/EFPowerToolsTemplates (kiểm tra các chi nhánh để thay đổi)

Sau đó, việc đặt tên của bạn có thể được tạo với tên tốt hơn.

+1

Bạn nên luôn luôn bao gồm đoạn mã/đoạn thích hợp nhất hoặc hai đoạn từ tài nguyên được liên kết, ngay cả khi chỉ để ngăn chặn liên kết mục nát. – bardzusny

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