5

Tôi có một cơ sở dữ liệu với các bảng rất lớn (một số có thể có hơn 1.000.000 bản ghi) và mọi người dùng cơ sở dữ liệu này sẽ thấy một số dữ liệu này, vì vậy chúng tôi có nhiều TVF (Bảng giá trị chức năng) có được một ID người dùng và chọn những bản ghi của bảng hiển thị cho người dùng đó (thao tác này yêu cầu nhiều câu lệnh SELECT và tôi nghĩ rằng gọi TVF là tốt hơn nhiều so với thực hiện nó trong mã). Trong bản phát hành đầu tiên của chương trình cho khách hàng của tôi, tôi đã có một lớp học với nhiều thuộc tính của loại IQueryable được triển khai bằng cách sử dụng LinqToSql và nó hoạt động rất tốt. Bây giờ tôi có một khách hàng muốn sử dụng assembly của tôi để viết một dịch vụ dữ liệu WCF, vì vậy tôi phải viết một lớp bắt nguồn từ DbContext (sử dụng EF) có thể được sử dụng trong dịch vụ được chỉ định. Vấn đề của tôi là:Tạo một bộ từ Bảng có giá trị trong khung thực thể

  • DbContext tự động phơi bày tất cả DbSet tài sản mà theo quy định tại nó, vì vậy mỗi người dùng với mức tối thiểu là truy cập có thể nhìn thấy toàn bộ dữ liệu của bảng (các ứng dụng dĩ nhiên khách hàng sẽ hạn chế dữ liệu, nhưng khách hàng có thể truy cập dữ liệu trực tiếp và thậm chí nhập dữ liệu đó vào Excel hoặc Truy cập bằng OData)

  • Tôi có nhiều thuộc tính công khai loại IQueryable nhưng chúng sẽ không xuất hiện trong danh sách dữ liệu tiếp xúc với dịch vụ dữ liệu WCF.

Để giải quyết vấn đề này, tôi nghĩ giải pháp hoàn thiện nhất là có thể gọi TVF làm bàn và tạo một bộ từ đó. Nhưng tôi không biết làm thế nào để làm điều này ?!

Note Bất kỳ sự thay đổi cơ sở dữ liệu yêu cầu một số khai thác gỗ, vì vậy tôi đã được lưu trữ thủ tục để làm những thay đổi đó, vì vậy tôi chỉ yêu cầu chỉ đọc truy cập vào dịch vụ dữ liệu WCF của tôi và tôi không muốn bộ mặc định có chứa tất cả các bản ghi của các bảng được xuất bản trong dịch vụ

+0

tôi không chắc chắn, nhưng tôi nghĩ bạn chỉ có thể sử dụng một câu lệnh Select giống như khi bạn chọn Select from a Table để điền dữ liệu. – Malachi

+0

@Malachi cảm ơn câu trả lời của bạn, nhưng tôi có thể (và thực sự tôi đã làm) lấy IQueryable từ TVF của tôi, nhưng vấn đề là dịch vụ dữ liệu WCF chỉ hiển thị tất cả các thuộc tính DbSet của DbContext của tôi, tôi muốn ẩn tất cả các thuộc tính và hiển thị thuộc tính IQueryable của tôi thay vào đó, nhưng tôi không biết làm thế nào! – BigBoss

+0

Bạn không thể tạo một lớp dịch vụ hạn chế quyền truy cập vào TVF của bạn? –

Trả lời

2

Tôi nghĩ rằng bạn có thể nhận được các chức năng bạn muốn bằng cách sử dụng một customized data service provider để xác định hình dạng của dịch vụ WCF của bạn. Điều đó có thể trở nên khá phức tạp, nhưng vì bạn đã có một loạt các IQueryables, có thể bạn sẽ có thể sử dụng số Reflection Provider, về các tài liệu nói:

Nhà cung cấp phản ánh hiển thị dữ liệu trong các lớp trả về các loại triển khai giao diện IQueryable. WCF Data Services sử dụng sự phản chiếu để suy ra một mô hình dữ liệu cho các lớp này và có thể dịch các truy vấn dựa trên địa chỉ đối với tài nguyên thành truy vấn dựa trên truy vấn tích hợp ngôn ngữ (LINQ) dựa trên các kiểu IQueryable được tiếp xúc.

Tài liệu đó liên kết đến "Cách thực hiện" để sử dụng Nhà cung cấp phản ánh. Về cơ bản, bạn chỉ cần tạo một lớp bối cảnh giả với các thuộc tính IQueryable, thêm một vài thuộc tính vào các đối tượng dữ liệu của bạn và trỏ DataService của bạn vào loại ngữ cảnh giả của bạn. (Nếu bạn đang sử dụng cơ sở dữ liệu/Mẫu đầu tiên EF, có thể bạn sẽ cần phải tạo partials của các thực thể của bạn để thêm các thuộc tính, hoặc cập nhật các mẫu T4.)

+0

Cảm ơn rất nhiều vì câu trả lời của bạn, trước đây tôi cố gắng sử dụng ReflectionProvider và gặp một số khó khăn, nhưng tôi sẽ thử bằng cách thay đổi các mẫu T4. Nhưng bạn có biết rằng nếu kỹ thuật này hỗ trợ MetadataTypeAttribute hay không? – BigBoss

+0

@BigBoss, tôi khá chắc chắn nó không; Tôi chỉ dotPeek'd bên trong ReflectionServiceProvider trong System.Data.Services và nó không sử dụng bất kỳ công cụ System.ComponentModel nào, nó chỉ tìm kiếm 'DataServiceKeyAttribute' trên các kiểu đối tượng dữ liệu. –

+0

Cảm ơn rất nhiều vì đã dành thời gian, tôi sẽ kiểm tra kỹ thuật của bạn – BigBoss

0

Tại sao không tạo thủ tục lưu trữ tham số được ghi lại tham số (SP) với UserID làm tham số? Entity Framework có thể làm việc với điều này.

Bạn có thể gọi TVF của bạn trong SP hoặc chỉ chuyển ngữ nội dung TVF trong SP.

Nếu bạn cần thêm/xóa/cập nhật chức năng, bạn có thể cần SP cho các chức năng đó, nếu truy vấn của bạn không thể cập nhật được.

+1

Điều đầu tiên là các hàm trong SQL không thể thay đổi cơ sở dữ liệu, nhưng SP có thể !! Và thứ hai là tôi không thể truy vấn dữ liệu từ SP và mong muốn trình tối ưu hóa để tối ưu hóa nó cho tôi (thay thế TABLE bằng SP là không thể) nhưng tôi có thể làm điều này với TVF và đó là lý do sự tồn tại của TVF (tôi đoán) – BigBoss

0

DbContext tự động phơi bày tất cả các thuộc tính DbSet rằng quy định tại nó

Tôi đề nghị, Bạn hãy xem trong Cơ sở dữ liệu Hoặc tận dụng Linq2Sql mẫu.

  1. Nếu bạn tạo chế độ xem, Trình thiết kế mẫu tạo DataTable thích hợp.
  2. Nếu bạn sử dụng mẫu linq2sql,
    Bạn có thể tạo mô hình dữ liệu chỉ có thuộc tính bạn muốn hiển thị cho những người khác.
    (Sau khi xóa kết nối trên linq2sql và phân bổ bằng connctionString, nó chỉ là cách sử dụng.)

Tôi có nhiều tài sản công cộng của loại IQueryable nhưng họ sẽ không xuất hiện trong danh sách các dữ liệu mà tiếp xúc bởi dịch vụ dữ liệu WCF.

Tạo mô hình và Sử dụng LINQ và phương pháp ExcuteJsonAll.
Nếu ai đó nhận tệp JSON, ai đó sẽ cung cấp tệp đó.

Cách đặt mô hình thành quy trình được lưu trữ.

  1. Chọn SP trong cơ sở dữ liệu.

  2. Cập nhật Mô hình của bạn từ Cơ sở dữ liệu

    Ở đây, bạn Đem SP.

  3. Trong edmx Hoặc chế độ xem mô hình, Bạn Thực hiện chức năng bằng SP.

  4. Trong khi tạo hàm, bạn có thể đặt giá trị trả về liên quan đến số liệu của sp.

+0

Cảm ơn bạn đã sự giúp đỡ của bạn, nhưng VIEWs sẽ không hoạt động vì tôi có nhiều người dùng (và người dùng có thể tạo người dùng mới) nên tôi không thể tạo chế độ xem mới cho từng người dùng và nếu tôi có thể sử dụng chúng bằng EF thì sao? – BigBoss

+0

Có thể, Sự cố đang trả về IQueryable . Thuộc tính của Model được mở cho User. Bạn nên chọn thủ tục. Và ... Từ sp được chọn, bạn tạo mô hình. – carbonara

+0

Chỉ cần trả về IQueryable, không giải quyết được vấn đề, tôi đã có thể trả lại một IQueryable từ TVF và điều này có hiệu suất tốt hơn từ SP. Nhưng vấn đề là tất cả các bộ sẽ được xuất bản với dịch vụ dữ liệu và người dùng có thể tải xuống và cũng là thuộc tính của loại IQueryable sẽ không được xuất bản bởi DataService, vì vậy người dùng không thể tải xuống chúng bằng các công cụ OData thông thường và chỉ có thể truy cập vào dữ liệu đó theo lập trình. Vì vậy, chúng tôi đã xuất bản dữ liệu không hợp lệ và dữ liệu chính xác bị ẩn! – BigBoss