2013-07-30 36 views
21

Tôi chỉ mới bắt đầu tìm hiểu về ASP.NET Web API và tôi có một vài điều mà vẫn chưa rõ ràng với tôi:sử dụng apicontroller vs OData EntitySetController

  • lý do tại sao tôi nên sử dụng EntitySetController, mà kế thừa từ bộ điều khiển OData thay vì ApiController
  • Tại sao EF thường được đề cập trong ngữ cảnh của OData. Tôi biết nó "đại diện" một thực thể, nhưng tôi không thấy lý do tại sao 2 được kết nối. Đầu tiên là trên Service Layer và EF là Model.
  • Tôi đã đọc và hiểu rất nhiều litereture viết về đề tài này, vâng tôi đã bỏ lỡ khi thực hành tốt nhất của nó

Thanks a lot, David

+2

Đây không phải là dựa trên ý kiến. Nó thậm chí không có mùi giống như một câu hỏi dựa trên ý kiến. Mọi người có thể bỏ phiếu để đóng làm điều này: đóng * sau khi * ý kiến ​​phân kỳ trở nên rõ ràng trong các câu trả lời. –

Trả lời

39

lý do tại sao tôi nên sử dụng EntitySetController, mà kế thừa từ bộ điều khiển OData thay vì ApiController

  • Tôi đồng ý rằng nó là khó hiểu và tài liệu hướng dẫn mà dường như được thiếu (ít nhất là khi tôi có cùng câu hỏi với bạn). Cách tôi đặt cảm xúc của tôi thoải mái chỉ đơn giản là đọc the code. Tôi khuyến khích bạn làm như vậy, vì nó thực sự rất ngắn (tập trung vào lớp EntitySetController và helpers); không nên mất hơn 5-10 phút (lời hứa) và bạn sẽ không có bất kỳ câu hỏi nào sau đó.

    Câu chuyện ngắn gọn là nó loại bỏ một số bản mẫu cho các trường hợp thông thường (nhưng tiếp tục đọc nếu bạn muốn thêm ngữ cảnh và ý kiến).

Tại sao EF thường được đề cập trong bối cảnh OData. Tôi biết nó "đại diện" một thực thể, nhưng tôi không thấy lý do tại sao 2 được kết nối. Đầu tiên là trên Service Layer và EF là Model.

  • Cái này nhầm lẫn tôi không ngừng quá, cho đến khi tôi đã từ bỏ và nhìn vào nguồn gốc của OData, các WCF Data Services (trước đây ADO.NET Data Services) và OData specifications (gợi ý là OData Lõi phiên bản giao thức vẫn được chỉ định với tiêu đề có tên "DataServicesVersion"). Ở đó, bạn có thể thấy rằng OData sử dụng EDM, Mô hình dữ liệu thực thể, cùng một đặc điểm kỹ thuật mô hình được EF sử dụng, và tuần tự hóa nó theo cùng định dạng như EF: CSDL (Ngôn ngữ định nghĩa lược đồ khái niệm). Đây không phải là trùng hợp ngẫu nhiên, WCF Data Services có hỗ trợ chính cho EF, và mặc dù nó không yêu cầu nó, người ta có thể nói rằng thiết kế của nó dựa trên nó.

    Lưu ý rằng Dịch vụ dữ liệu WCF vẫn là là triển khai hàng đầu của OData.

Cái gì đó là khả năng của lãi suất cao (ít nhất là đối với tôi): Khi sử dụng EF với Web API và OData mở rộng ASP.NET, không có cách nào (như xa như tôi biết) đến chia sẻ mô hình giữa hai người.

Bạn có thể bỏ qua điểm bullet tiếp theo cho câu trả lời tiếp theo nếu bạn không thấy điều này thú vị.

Ví dụ, khi sử dụng EF trong thiết lập Mã-Đầu tiên, bạn thường sẽ xây dựng mô hình của mình chủ yếu dựa trên các quy ước mã và EF System.Data.Entity.DbModelBuilder ("API chất lỏng"). Sau đó, bạn sẽ sử dụng các System.Web.Http.OData.Builder.ODataConventionModelBuilder mà sẽ làm khá nhiều chính xác cùng một điều để xây dựng mô hình OData, và đến khá nhiều tại cùng một kết quả chính xác. Trong quá khứ, tôi đã cố gắng khai thác một số ghi chú ngẫu nhiên từ một cuộc họp ngẫu nhiên từ nhóm EF hoặc nhóm API Web đã đề cập đến điều này một thời gian ngắn, và theo như tôi có thể nhớ (tôi không thể tìm thấy tài liệu này nữa), ở đó không có kế hoạch cải thiện tình hình. Vì vậy, bây giờ họ có hai triển khai EDM khác nhau và không tương thích.

Tôi thừa nhận tôi không dành thời gian để xem xét mã này để xác minh điều này, nhưng tôi biết rằng API Web + OData mở rộng phụ thuộc vào EdmLib (cung cấp Microsoft.Data.Edm ban đầu được phát triển cho Dịch vụ dữ liệu WCF), trong khi EF không, và thay vào đó sử dụng thực hiện System.Data.Entity.Edm của riêng nó. Tôi cũng biết rằng các nhà xây dựng mô hình dựa trên quy ước của họ là khác nhau, như đã giải thích ở trên. Nó trở nên vô lý khi bạn sử dụng EF trong thiết lập DB-First; bạn nhận được một mô hình EDM được tuần tự hóa theo định dạng CSDL trong EDMX file và các phần mở rộng OData tiếp tục và tạo mã CSDL được tuần tự hóa riêng của chúng khi chạy từ mã CLR (sử dụng các quy ước mã riêng) được tạo ra bởi EF từ CSDL ban đầu thông qua các mẫu T4. Đầu của bạn quay nhiều?


Cập nhật: Đây là largely improved một chút dưới hai tuần trước (19 tháng 7), xin lỗi tôi đã bỏ lỡ đó. (Cảm ơn RaghuRam Nadiminti.) Tôi đã không xem xét bản vá, nhưng từ mã mẫu có vẻ như cách nó hoạt động là người ta phải tuần tự hóa mô hình thành CSDL bằng cách sử dụng bộ chỉnh sửa EF EDMX, sau đó deserialize nó bằng cách sử dụng trình phân tích cú pháp EdmLib được sử dụng bởi các phần mở rộng OData. Nó vẫn cảm thấy một chút giống như một hack trong EF Code-First thiết lập (ít nhất là mã CLR chỉ được phân tích một lần, nhưng tôi sẽ thích nó nếu cả hai thành phần sử dụng cùng một bộ nhớ trong mô hình để bắt đầu với). Một lối tắt có thể được thực hiện khi sử dụng các kịch bản Model-First hoặc Database-First tuy nhiên, bằng cách deserializing tập tin EDMX được tạo ra bởi VS trực tiếp. Trong kịch bản cuối cùng nó thực sự cảm thấy ít giống như một hack, nhưng một lần nữa, một mô hình duy nhất sẽ là tốt nhất. Tôi không biết rằng EF có thể chuyển sang sử dụng EdmLib hay EdmLib sẽ chuyển sang sử dụng mô hình EDM của EF, cả hai dự án đều thực sự mạnh mẽ và các trình chặn có lẽ không chỉ là vấn đề kỹ thuật. Nhóm nghiên cứu ASP.NET tiếc là không thể làm nhiều về nó AFAICT.



Cập nhật: ngẫu nhiên stumbled khi those meeting notes một lần nữa. Họ thực sự đến từ đội ngũ EF và cho biết họ không có ý định làm việc với EdmLib.


Tuy nhiên, bây giờ tôi tin rằng đây là một điều tốt. Lý do là nếu họ đóng tất cả các khoảng trống, và loại bỏ tất cả các boilerplate, và làm cho tất cả mọi thứ đúng, họ về cơ bản sẽ kết thúc nơi WCF dịch vụ dữ liệu được, mà là một giải pháp tích hợp đầy đủ, nơi các lập trình viên tiêm mã trong đường ống thông qua " Đánh chặn ".Đối với tôi, lý do duy nhất để đến đó là vì các yêu cầu nguồn mở, nhưng ngay cả khi đó, tôi nghĩ sẽ hợp lý hơn khi thử và bênh vực cho một WCF-DS nguồn mở thay thế.

Câu hỏi bây giờ sẽ trở thành: "Nhưng Web API + mở rộng OData tốt nhất là gì?". Vâng, nó phù hợp khi bạn thực sự muốn hai mô hình khác nhau cho kho dữ liệu và dịch vụ web của bạn. Nó phù hợp khi thiết kế "chặn" không đủ linh hoạt để bạn dịch giữa hai mô hình.


Cập nhật: Tính đến 27 tháng ba năm 2014, nó chính thức, họ sẽ cố gắng để đóng những khoảng trống, deprecating WCF Data Services in the process. Các cuộc đàm phán rất sớm đề cập đến một "xử lý" để làm điều này, rất có thể là một trình xử lý HTTP ASP.NET (xem các bình luận trên thông báo). Có vẻ như rất ít kế hoạch đã đi vào điều này, vì họ vẫn động não ý tưởng để làm cho ASP.NET Web API điền vào các trường hợp sử dụng của WCF Data Services. Tôi đã đề cập đến các trường hợp sử dụng nêu trên, trong nhận xét về thông báo và trong this thread (bắt đầu một vài ngày trước khi thông báo).

Nhiều người khác bày tỏ mối quan tâm gần giống nhau (một lần nữa, xem các cuộc thảo luận được liên kết), vì vậy thật tốt khi thấy rằng tôi chưa từng mơ về điều này.

Có một số sự hoài nghi rằng ASP.NET Web API có thể được biến thành một cái gì đó hữu ích cho các trường hợp sử dụng dịch vụ dữ liệu trong một thời gian hợp lý, vì vậy một số người suggested that MSFT reconsider their decision. Câu hỏi liệu có nên sử dụng ASP.NET cho các yêu cầu mã nguồn mở hay không cũng là tranh luận: WCF Data Services sẽ sớm có nguồn mở nếu tất cả đi "tốt", mặc dù không nhờ vào bất kỳ nỗ lực vận động nào. (Nó chỉ là một bãi chứa nguồn, nó không rõ nếu bất cứ ai sẽ duy trì nó vào thời điểm này.)

Từ những gì tôi có thể thu thập, tất cả mọi thứ chỉ để cắt giảm ngân sách, và một số người nói về nó là kết quả của toàn công ty "tái tập trung", mặc dù tất cả điều này nên được thực hiện với một hạt muối.

Những thứ này sang một bên, bây giờ có khả năng là với thời gian, một giải pháp mới xuất hiện - thậm chí tốt hơn là WCF Data Services hoặc Web API khi nói đến OData APIs. Mặc dù có vẻ hơi hỗn loạn ngay bây giờ, nhóm MSFT ODFT đã nhận được khá nhiều phản hồi từ khách hàng của mình khá sớm, do đó, có hy vọng (đặc biệt nếu giải pháp trong tương lai, nên có một, chính nó là nguồn mở). Quá trình chuyển đổi có thể sẽ gây đau đớn, nhưng hãy chắc chắn xem các cuộc thảo luận xung quanh vấn đề này trong tương lai.

Tôi không chắc mình sẽ dành thời gian cập nhật bài đăng này nữa; Tôi chỉ muốn nhấn mạnh rằng những thứ liên quan đến Web API và dịch vụ dữ liệu sắp thay đổi rất nhiều, vì câu trả lời này vẫn đang được upvoted theo thời gian.



Cập nhật:RESTier (announcement) có vẻ là kết quả.


Và cuối cùng, ý kiến ​​cá nhân của tôi: OData, mặc dù về mặt kỹ thuật là giao thức dựa trên HTTP RESTful, rất, rất, rất theo định hướng dữ liệu. Điều này là hoàn toàn tốt (chúng ta có thể định nghĩa nhiều loại giao diện khác nhau với HTTP) và tôi, cho một, tìm tất cả các cuộc tranh luận của ServiceStack vs OData không liên quan (tôi tin rằng chúng hoạt động ở các tầng khác nhau trong các kiến ​​trúc phổ biến hiện tại của chúng ta). Những gì tôi thấy đáng lo ngại là những người đang cố gắng tạo ra một hành động API dựa trên OData giống như API trung tâm hành vi (hoặc "theo quy trình" hoặc "ServiceStack").Với tôi, các quy ước OData URI và các định dạng biểu diễn tài nguyên (Atom và JSON) cùng nhau thay thế SQL, WCF Data Services "Query Interceptors" and "Change Interceptors" thay thế các trình kích hoạt DBMS và thay thế các thủ tục lưu sẵn DBMS. Với quan điểm này, bạn ngay lập tức thấy rằng nếu logic miền bạn cần đặt phía sau API OData của bạn quá phức tạp hoặc không theo định hướng dữ liệu, bạn sẽ kết thúc với "Hành động" phức tạp không tôn trọng nguyên tắc REST và các thực thể không cảm thấy đúng. Nếu bạn xử lý API OData của bạn như một lớp dữ liệu thuần túy, bạn vẫn ổn. Bạn có thể xếp chồng một dịch vụ lên trên nó giống như bạn sẽ đặt một "lớp dịch vụ" trên cơ sở dữ liệu SQL.

Và do đó, tôi không chắc chắn Web API + OData mở rộng là tuyệt vời nữa. Nếu bạn cần các mô hình cơ bản khác nhau, có khả năng ứng dụng của bạn không quá định hướng dữ liệu (ngoại trừ nếu bạn chỉ đơn giản hợp nhất các mô hình từ nhiều nguồn khác nhau) và OData không phù hợp. Đây là một dấu hiệu bạn nên ít nhất xem xét Web API một mình (với SQL hoặc OData dưới đây) hoặc một cái gì đó như ServiceStack.

Để tốt hơn hoặc tệ hơn, khách hàng Javascript không thể nói SQL với máy chủ từ xa. Có lẽ trong tương lai thông qua các API của trình duyệt, hoặc có thể thông qua các biến thể của WebSockets, nhưng ngay bây giờ, OData là điều gần nhất với lớp dữ liệu từ xa mà bất kỳ ai sẽ nhận được cho các máy khách JS phong phú có logic bên máy chủ hoặc không có logic. OData được sử dụng bởi các loại máy khách khác của khóa học, nhưng tôi sẽ nói rằng nó đặc biệt hữu ích trên nền tảng web phía máy khách, nơi những thứ như Breeze.js hoặc JayData là OData những gì mà Entity Framework là SQL.

Tôi đã đọc và hiểu rất nhiều litereture viết về đề tài này, vâng tôi đã bỏ lỡ khi nó thực hành tốt nhất

  • Đừng lo lắng, tôi nhìn xung quanh, nhưng tôi don' t nghĩ rằng bất cứ ai thực sự biết những gì họ đang làm. Chỉ cần giả vờ như mọi người khác trong khi bạn có ý thức về mớ hỗn độn này.
+0

câu trả lời tuyệt vời Một điều nhỏ là API Web API có thể hỗ trợ IEdmModel được tạo ra bên ngoài. [Vấn đề này] (https://aspnetwebstack.codeplex.com/workitem/802) Vì vậy, nếu bạn muốn để lộ cơ sở dữ liệu của bạn như bây giờ, bạn có thể bây giờ –

+0

Cập nhật với một giải thích của bản vá của bạn (công việc tuyệt vời BTW, tôi hy vọng tôi đã nhận nó ngay!) – tne

+0

và câu trả lời dài (theo cách tốt. =)) Và tôi thích câu trả lời của bạn cho câu hỏi cuối cùng nhất Hahaha, mặc dù tôi hy vọng điều đó không đúng sau vài năm. =) –

0

Sử dụng EntitySetController nếu bạn muốn tạo một OData điểm cuối. Sử dụng ApiController nếu bạn muốn trả về JSON hoặc XML chung hoặc một số định dạng khác (ví dụ: sử dụng trình định dạng tùy chỉnh).

Trong API Web, EF và OData không nhất thiết phải được kết nối. Bạn có thể viết một điểm cuối OData không sử dụng EF. Rất nhiều các hướng dẫn API Web sử dụng EF, vì mã đầu tiên của EF tương đối dễ hiển thị trong một hướng dẫn. :-)

+0

Cảm ơn, nhưng khi nào tôi muốn một điểm cuối OData? Ví dụ, tôi có một lớp "A" và 3 lớp khác kế thừa từ A: A1, A2 và A3. Tôi muốn trưng bày các hoạt động CRUD cho A1, A2 và A3. Tôi có nên tạo cho mỗi người trong số họ (tôi muốn 3 bộ điều khiển khác nhau) một ApiController hoặc EntitySetController? –

+0

Thông thường bạn muốn có một điểm cuối duy nhất cho mỗi "dịch vụ"; đây là một quyết định kiến ​​trúc. Mỗi API Web đại diện cho một điểm cuối OData (cái mà tôi gọi là API Web là "thứ mà bạn ánh xạ một mô hình ODataRoute và EDM tới) .Một mô hình có nhiều thực thể (ba lớp của bạn). Mỗi thực thể được điều khiển bởi một ODataController duy nhất , có thể là một EntitySetController (chỉ mở rộng lớp ODataController) – tne

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