6

Tôi có một tình huống mà tôi muốn sử dụng một lớp logic nghiệp vụ duy nhất để thực hiện các hoạt động tương tự trên một loạt các lớp khung thực thể. Tôi đã định nghĩa một giao diện mà các lớp này thực hiện trong một tệp lớp một phần.LINQ to Entities thông qua thuộc tính giao diện

Tuy nhiên khi tôi cố gắng viết LINQ cho các truy vấn thực thể đối với các phương thức giao diện này, tôi nhận được NotSupportedException vì truy vấn không trực tiếp sử dụng thuộc tính của lớp mà thông qua giao diện.

Tôi muốn giữ nâng hạng nặng lên tầng cơ sở dữ liệu để có cách nào để đạt được điều này mà không cần sử dụng LINQ cho các đối tượng?

Dưới đây là một số mã chứng minh sự cố của tôi (nó đang sử dụng một lớp lưu trữ chung được tạo bởi một nhà máy).

public interface INamedEntity 
{ 
    int ID { get; set; } 
    string Name { get; set; } 
} 

// This is an Entity Framework class which has CustomerID and CustomerName properties. 
public partial class Customer: INamedEntity 
{ 
    int INamedEntity.ID 
    { 
     get { return this.CustomerID; } 
     set { this.CustomerID = value; } 
    } 
    string INamedEntity.Name 
    { 
     get { return this.CustomerName; } 
     set { this.CustomerName = value; } 
    } 
} 

... 

public string GetName<T>(int entityID) where T: EntityObject, INamedEntity 
{ 
    using(var repository = RepositoryFactory.CreateRepository<T>()) 
    { 
     return repository 
      .Where(e => e.ID == entityID) 
      .Select(e.Name) 
      .Single(); 
    } 
} 

Trả lời

0

Ngoại lệ sau xảy ra khi thực hiện truy vấn dựa trên nguồn chung và với thành viên giao diện được sử dụng trong mệnh đề where.

NotSupportedException: Ánh xạ thành viên giao diện [InterfaceName]. [MemberName] không được hỗ trợ.

Ngoại lệ chỉ xảy ra khi truy vấn trả về nhiều mục và khi tôi sử dụng toán tử ==. Tôi không thể tạo lại lỗi khi thực thi truy vấn với First, FirstOrDefault hoặc Single, hoặc khi tôi sử dụng bằng hoặc toán tử khác trong mệnh đề where.

Tham chiếu: Interface not supported

+0

Vâng, có vẻ như vấn đề. – gareththegeek

5

Điều này không được hỗ trợ. Truy vấn LINQ-to-entity của bạn chỉ có thể sử dụng các thuộc tính được ánh xạ của các thực thể của bạn. Nếu bạn sử dụng thuộc tính giao diện EF không biết cách chuyển đổi chúng thành SQL vì nó không thể phân tích mã của bạn trong việc triển khai thuộc tính.

Không sử dụng giao diện cho thực thể - EF không hỗ trợ gì cả. Trong trường hợp đặc biệt của bạn, nó thậm chí sẽ không hoạt động với bất kỳ ORM nào khác bởi vì bạn đang truy vấn trên các thuộc tính không biết ánh xạ. Điều này sẽ yêu cầu bạn xây dựng nhà cung cấp LINQ của riêng bạn dịch truy vấn của bạn để truy vấn với các thuộc tính được ánh xạ thực.

+0

Nhưng có cách nào để đạt được kiểu mẫu này không. Lý tưởng nhất là sẽ có các đơn vị logic kinh doanh cho từng lĩnh vực chức năng, làm việc trên một giao diện và ánh xạ tới tất cả các thực thể có liên quan. – gareththegeek

+1

Nhưng điều đó có nghĩa là một lớp "ánh xạ" khác trên EF sẽ dịch các thuộc tính giao diện logic nghiệp vụ của bạn thành các thuộc tính EF thực. Lớp ánh xạ này cũng sẽ chuyển đổi các truy vấn. Tôi không gọi mẫu này - tôi gọi nó qua ứng dụng kiến ​​trúc. –

+0

Có thể kiến ​​trúc quá mức, nhưng làm cách nào để tránh sao chép và dán cùng một mã vào một số đối tượng lớp kinh doanh để chúng có thể thực hiện cùng một logic, nhưng sử dụng các thuộc tính thực thể khác nhau? – gareththegeek

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