2012-05-09 25 views
6

Tôi tò mò về cách tạo thuộc tính có thể được dịch bởi LINQ. Dưới đây là một ví dụ rất đơn giản.Tạo thuộc tính mà LINQ to Entities có thể dịch

Tôi có một bảng/lớp Category, mà có một cột ParentId liên kết với chính nó (Vì vậy, một loại có thể có tiểu mục)

EF tự động tạo ra một tài sản Category1, đó là chủ đề chính.

Vì lợi ích của sự rõ ràng, tôi tạo ra tài sản khác

public partial class Category 
{ 
    public Category Parent 
    { 
    get { return Category1; } 
    } 
} 

Vấn đề là, công trình này

var categs = ctx.Categories.Where(x => x.Category1 == null); 

nhưng điều này không làm việc

var categs = ctx.Categories.Where(x => x.Parent == null); 

Các thành viên loại được chỉ định 'Phụ huynh' 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ợ.

Có cách nào để tạo thuộc tính có thể dịch (LINQ to SQL) mà không làm .ToList()?

EDIT: Tôi muốn tránh chạm Model.edmx vì cơ sở dữ liệu thường xuyên thay đổi trong quá trình phát triển và .edmx thường cần phải được tái

+0

bạn cần tạo thuộc tính điều hướng từ danh mục cho phụ huynh như khóa ngoài –

+0

Xin chào, tôi rất tiếc, tôi không chắc chắn ý của bạn là gì. Đã có một khóa ngoại (Nếu không EF sẽ không tạo Category1) – Aximili

+0

Bạn đã thực sự nhìn vào 'Category1' trong Model.Designer.cs và/hoặc Reflector để xem thuộc tính nào hay các vật liệu khác được thêm vào định nghĩa của nó? –

Trả lời

2

Nếu bạn hỏi liệu có thể tạo thuộc tính với bất kỳ mã C# nào trong getters/setters và sau đó nó có được hiểu bởi LINQ to Entities chuẩn hay không thì không thể thực hiện được. C# là biểu cảm hơn sau đó SQL và nó không hợp lý để mong đợi Entity Framework hoạt động như một trình dịch C# tới SQL chung.

Bạn có thể làm việc xung quanh đây là nhiều trường hợp, xem Using a partial class property inside LINQ statement để biết ví dụ.

Cập nhật

Nó muốn giúp đỡ nếu bạn nói với chúng tôi một cách chính xác những gì bạn muốn đạt được, nhưng đây là một ví dụ:

public partial class Category 
{ 
    public static Expression<Func<Category, bool>> ParentIsNullExpression 
    { 
     get 
     { 
      return c => c.Category1 == null; 
     } 
    } 
} 

Và sau đó

var categs = ctx.Categories.Where(Category.ParentIsNullExpression); 

Tất cả các loại thao tác trên Expressions là có thể, một số trong số chúng được hỗ trợ bởi EF và như vậy dịch sang SQL.

+0

Nó không thể được thực hiện trong C#? Nhưng bản thân Model.Designer.cs (tệp CS cho EDMX) là C#, phải không? Bạn đang đề cập đến Thuộc tính trả về Biểu thức từ liên kết đó? Tôi sẽ xem xét nó. – Aximili

+0

Có, tôi đang đề cập đến Thuộc tính biểu thức. Đó không phải là mã thuộc tính làm cho nó hoạt động trong Model.Designer.cs, đó là biểu thức bạn sử dụng để truy cập thuộc tính, ví dụ: '' c => c.Category''. EF biết rằng bạn muốn thuộc tính '' Category'' và dịch thành cột/bảng '' Category''. –

+0

Xin lỗi tôi chưa bao giờ sử dụng Thuộc tính Biểu thức. Bạn có nói rằng nó có thể là một thuộc tính biểu thức được dịch sang SQL? Bạn có thể thay thế thuộc tính Gốc trong câu hỏi của tôi bằng Thuộc tính Biểu thức để LINQ có thể dịch nó không? Cảm ơn Jacek – Aximili

0

trong thiết kế Entity Data Model của bạn (tập tin .edmx), bạn có thể đổi tên Category1 to Parent

+0

Đó chỉ là một ví dụ rất đơn giản. Tôi đã hỏi làm thế nào để viết một tài sản, không đổi tên một hiện có. Dù sao cũng cảm ơn bạn. – Aximili

0

Bạn có 4 lựa chọn:

  1. Sử dụng mã đầu tiên
  2. Thêm nó vào nhà thiết kế EDMX
  3. Thêm tài sản của mình vào phần CSDL của EDMX, thêm một cột vào phần SSDL của EDMX, sau đó ánh xạ chúng với nhau trong phần lập bản đồ của EDMX.
  4. Đưa truy vấn vào bộ nhớ bằng .ToList() sau đó sử dụng LINQ nội bộ thay vì LINQ to Entities.
Các vấn đề liên quan