ADO.NET Data Services (後稱 WCF Data Services) 讓資料以 REST 風格的 URI 公開,支援 LINQ 查詢、JSON/AtomPub 格式。本文以 Northwind 為例,示範服務端與用戶端實作。
public class Service : DataService<VS2008SP1.Business.NorthwindEntities> {
public static void InitializeService(IDataServiceConfiguration config) {
// 開放所有實體集的完整存取權限
config.SetEntitySetAccessRule("*", EntitySetRights.All);
}
// 查詢攔截器:限制 Orders 僅回傳 ContactName 為 Paul Henriot 的資料
[QueryInterceptor("Orders")]
public Expression<Func<Orders, bool>> FilterOrders() {
return o => o.Customers.ContactName == "Paul Henriot";
}
}
public partial class DataServices_Demo : System.Web.UI.Page {
Uri _uri = new Uri("https://localhost:7002/DataServices/Service.svc/", UriKind.Absolute);
void BindData() {
NorthwindEntities ctx = new NorthwindEntities(_uri);
GridView1.DataSource = ctx.Categories;
GridView1.DataBind();
}
protected void btnAddCategory_Click(object sender, EventArgs e) {
NorthwindEntities ctx = new NorthwindEntities(_uri);
Categories category = new Categories { CategoryName = txtCategoryName.Text, Description = txtDescription.Text };
ctx.MergeOption = MergeOption.AppendOnly;
ctx.AddToCategories(category);
// 批次新增 10 筆產品並建立關聯
for (int i = 0; i < 10; i++) {
var product = new Products { ProductName = "測試用" + i };
product.Categories = category;
ctx.AddToProducts(product);
ctx.SetLink(product, "Categories", category); // 多對一
}
ctx.SaveChanges(SaveChangesOptions.Batch);
BindData();
}
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e) {
NorthwindEntities ctx = new NorthwindEntities(_uri);
var categoryId = (int)GridView1.DataKeys[e.RowIndex].Value;
var category = ctx.Categories.Where(p => p.CategoryID == categoryId).First();
ctx.LoadProperty(category, "Products"); // 載入導航屬性以便級聯刪除
foreach (var product in category.Products) ctx.DeleteObject(product);
ctx.DeleteObject(category);
ctx.SaveChanges();
BindData();
}
// ... 更新、查詢明細等事件處理
}
void Demo() {
// URI 語法查詢
DataServiceContext ctx = new DataServiceContext(_uri);
DataServiceQuery<Categories> categories = ctx.CreateQuery<Categories>("/Categories");
foreach (var c in categories) result.InnerHtml += c.CategoryID + ",";
}
void Demo2() {
// 非同步查詢
DataServiceQuery<Categories> query = ctx.CreateQuery<Categories>("/Categories");
query.BeginExecute(ar => {
foreach (var c in query.EndExecute(ar)) result.InnerHtml += c.CategoryID + ",";
}, null);
}
void Demo3() {
// 查詢攔截器效果驗證
NorthwindEntities ctx = new NorthwindEntities(_uri);
foreach (var o in ctx.Orders) result.InnerHtml += o.OrderID + ","; // 只會得到 Paul Henriot 的訂單
}
void Demo4() {
// 要求 JSON 格式回應
WebClient client = new WebClient();
client.Headers.Add("accept", "application/json");
result.InnerHtml += HttpUtility.HtmlEncode(client.DownloadString(_uri));
}
DataService<T> 為服務進入點,IDataServiceConfiguration.SetEntitySetAccessRule 控制權限。QueryInterceptorAttribute 實作資料列層級安全性過濾。DataServiceContext 與 DataServiceQuery,支援 LINQ、URI 語法、非同步、批次更新。