2011-01-09 26 views
5

Vì vậy, nó chỉ ra rằng tôi là người cuối cùng để khám phá sàn cơ bản tồn tại trong khuôn khổ thực thể của Microsoft khi thực hiện TPT (Bảng Per Type) thừa kế. Đã xây dựng một mẫu thử nghiệm với 3 lớp phụ, bảng/lớp cơ sở gồm 20 cột và bảng con gồm ~ 10 cột, mọi thứ hoạt động tốt và tôi tiếp tục làm việc trên phần còn lại của ứng dụng đã chứng minh khái niệm. Bây giờ thời gian đã đến để thêm 20 loại phụ khác và OMG, tôi vừa mới bắt đầu tìm kiếm SQL được tạo ra trên một lựa chọn đơn giản, mặc dù tôi chỉ quan tâm đến việc truy cập vào các trường trên lớp cơ sở.Biểu mẫu thực thể Bảng Per Type Hiệu suất

This page có mô tả tuyệt vời về sự cố.

Có ai đi vào sản xuất sử dụng TPT và EF, đang có cách giải quyết bất kỳ mà sẽ có nghĩa là tôi sẽ không phải: a) Chuyển đổi schema để TPH (mà đi ngược lại tất cả những gì tôi cố gắng để đạt được với tôi Thiết kế DB - urrrgghh!)? b) viết lại bằng ORM khác?

Cách tôi xem, tôi có thể thêm tham chiếu vào Thủ tục được lưu trữ từ trong EF (có thể sử dụng EFExtensions) có TSQL chỉ chọn các trường tôi cần, thậm chí sử dụng mã được tạo bởi EF cho con quái vật UNION/JOIN bên trong SP sẽ ngăn chặn SQL được tạo ra mỗi khi một cuộc gọi được thực hiện - không phải cái gì tôi sẽ có ý định làm, nhưng bạn có được ý tưởng.

Kẻ giết người tôi đã tìm thấy, là khi tôi chọn danh sách các thực thể được liên kết với bảng cơ sở (nhưng thực thể tôi chọn không phải là bảng phân lớp) và tôi muốn lọc theo pk của bảng Base, và tôi làm .Include("BaseClassTableName") để cho phép tôi lọc bằng cách sử dụng x=>x.BaseClass.PK == 1 và truy cập các thuộc tính khác, nó cũng thực hiện thế hệ SQL mẹ ở đây.

Tôi không thể sử dụng EF4 vì tôi bị giới hạn trong thời gian chạy .net 2.0 với cài đặt 3.5 SP1.

Có ai có bất kỳ trải nghiệm nào để thoát khỏi mớ hỗn độn này không?

+1

tôi không thể nói cho EF4 trước, nhưng trong blog của tuyên bố "Bảng-Per-Type thừa kế là 100% không sử dụng được. " là một chút vô lý - ít nhất là trong EF4. Nó có một số vấn đề hiệu suất có - nhưng nếu bạn có 20 loại phụ, bạn có chắc là bạn đã thực hiện chuẩn hóa cơ sở dữ liệu chính xác không? Có thể 20 loại phụ đó không được chia thành các thực thể cha mẹ riêng biệt không? – RPM1984

+2

Dường như các ORM khác xử lý thiết kế TPT mà không có vấn đề gì. Liên quan đến blog, nó nói rằng khi thực hiện một cơ sở dữ liệu/lớp thiết kế có một số lượng lớn các loại, thời gian cần để tạo ra SQL trước khi thực thi lớn hơn vài phút, tôi tin rằng đó là đủ để sao lưu câu lệnh nó không thể sử dụng được trong môi trường sản xuất. Hãy suy nghĩ về một danh mục xe, với thông tin chung được lưu trữ về mọi xe (bảng/lớp cơ sở) và thông tin duy nhất được lưu trữ về máy bay/xe lửa/điện thoại di động (bảng phụ/lớp) - Tôi không giao dịch với xe, nhưng bạn lấy ý tưởng – Tr1stan

+1

... và có> 20 loại xe khác nhau đang được lưu trữ, trước khi bạn bắt đầu đi vào các loại xe phụ và tất cả các giá trị tra cứu. – Tr1stan

Trả lời

1

Điều này có vẻ hơi nhầm lẫn. Bạn đang nói về TPH, nhưng khi bạn nói:

Cách tôi nhìn thấy, tôi sẽ có thể thêm tham chiếu đến Thủ tục được lưu trữ từ trong EF (có thể sử dụng EFExtensions) có TSQL chỉ chọn các trường mà tôi cần, ngay cả khi sử dụng mã được tạo bởi EF cho UNION/JOIN của con quái vật bên trong SP sẽ ngăn chặn SQL được tạo ra mỗi lần thực hiện cuộc gọi - không phải thứ tôi định làm, nhưng bạn có ý tưởng.

Vâng, đó là Bảng theo sơ đồ lớp bê tông (sử dụng proc thay vì bảng, nhưng vẫn là ánh xạ là TPC ...). EF hỗ trợ TPC, nhưng nhà thiết kế thì không. You can do it in code-first if you get the CTP.

giải pháp ưa thích của bạn sử dụng một proc sẽ gây ra vấn đề hiệu suất nếu bạn hạn chế truy vấn, như thế này:

var q = from c in Context.SomeChild 
     where c.SomeAssociation.Foo == foo 
     select c; 

Các DB ưu không thể nhìn thấy thông qua việc thực hiện proc, vì vậy bạn sẽ có được một quét toàn bộ các kết quả.

Vì vậy, trước khi bạn tự nhủ rằng điều này sẽ khắc phục kết quả của bạn, hãy kiểm tra lại giả định đó.

Lưu ý rằng bạn luôn có thể chỉ định SQL tùy chỉnh cho bất kỳ chiến lược lập bản đồ nào với ObjectContext.ExecuteStoreQuery.

Tuy nhiên, trước khi bạn thực hiện bất kỳ điều nào trong số này, hãy xem xét rằng, như RPM1984 chỉ ra, thiết kế của bạn dường như lạm dụng thừa kế. Tôi thích this quote from NHibernate in Action

[A] sk cho dù có thể tốt hơn là sửa lại kế thừa làm đại biểu trong mô hình đối tượng. Thừa kế phức tạp thường tránh được tốt nhất cho tất cả các loại lý do không liên quan đến sự tồn tại hoặc ORM. [ORM của bạn] hoạt động như một bộ đệm giữa đối tượng và các mô hình quan hệ, nhưng điều đó không có nghĩa là bạn hoàn toàn có thể bỏ qua những lo ngại về sự kiên trì khi thiết kế mô hình đối tượng của bạn.

+0

Cảm ơn Craig, tôi chỉ đề cập đến TPH như một phương sách cuối cùng - những gì tôi thực sự cố gắng đạt được là TPT - tôi đoán tôi không xem xét 1 lớp/bảng cơ sở và 1 cấp lớp con/bảng khác để thừa kế phức tạp . Nhưng sau đó có lẽ bạn đang đề cập đến bề rộng của thiết kế lớp học của tôi là quá "rộng" phức tạp (~ 23 lớp con) - mặc dù tôi không thể có vẻ để có được đầu của tôi xung quanh một cách sạch hơn của sự bền bỉ các lớp học. – Tr1stan

+0

Ồ, và tôi đã đề cập đến phương pháp SP truy vấn như là một thay thế cho đề xuất của bạn với ObjectContext.ExecuteStoreQuery - Một lần nữa, tôi chỉ hy vọng rằng tôi đã bỏ lỡ một cái gì đó rõ ràng rõ ràng rằng một trong những bạn khôn ngoan dân gian có thể đã chỉ cho tôi tại. – Tr1stan

2

Chúng tôi đã gặp sự cố tương tự này và đang xem xét việc chuyển DAL của chúng tôi từ EF4 sang LLBLGen vì điều này.

Trong khi đó, chúng tôi đã sử dụng các truy vấn biên soạn để làm giảm bớt phần nào nỗi đau:

Compiled Queries (LINQ to Entities)

Chiến lược này không ngăn cản các truy vấn khổng lồ, nhưng thời gian cần thiết để tạo ra các truy vấn (có thể rất lớn) chỉ được thực hiện một lần.

truy vấn Bạn sẽ có thể sử dụng được biên soạn với Bao gồm() như vậy:

static readonly Func<AdventureWorksEntities, int, Subcomponent> subcomponentWithDetailsCompiledQuery = CompiledQuery.Compile<AdventureWorksEntities, int, Subcomponent>(
     (ctx, id) => ctx.Subcomponents 
      .Include("SubcomponentType") 
      .Include("A.B.C.D") 
      .FirstOrDefault(s => s.Id == id)); 

    public Subcomponent GetSubcomponentWithDetails(int id) 
    { 
     return subcomponentWithDetailsCompiledQuery.Invoke(ObjectContext, id); 
    } 
Các vấn đề liên quan