ApplyChanges 即可同步資料庫。public class BLL
{
public List<ProductCategory> GetCategories()
{
using (var ctx = new SelfTrackingEntities())
return ctx.ProductCategories.ToList();
}
public ProductCategory GetCategory(int id)
{
using (var ctx = new SelfTrackingEntities())
return ctx.ProductCategories.Single(c => c.ProductCategoryID == id);
}
public void UpdateCategory(ProductCategory cat)
{
using (var ctx = new SelfTrackingEntities())
{
ctx.ProductCategories.ApplyChanges(cat);
ctx.SaveChanges();
}
}
public void DeleteCategory(ProductCategory cat)
{
cat.MarkAsDeleted();
UpdateCategory(cat);
}
public void AddCategory(ProductCategory cat)
{
UpdateCategory(cat); // 新增也走 ApplyChanges
}
}
protected void ListView1_ItemUpdating(object sender, ListViewUpdateEventArgs e)
{
var bll = new BLL();
var cat = bll.GetCategory((int)ListView1.DataKeys[e.ItemIndex].Value);
cat.StartTracking(); // 非 WCF 情境必須手動呼叫
cat.Name = e.NewValues["Name"].ToString();
bll.UpdateCategory(cat);
ListView1.EditIndex = -1;
e.Cancel = true;
}
[ServiceContract]
public interface IMyService
{
[OperationContract] List<ProductCategory> GetCategories();
[OperationContract] ProductCategory GetCategory(int categoryId);
[OperationContract] int UpdateCategory(ProductCategory category);
[OperationContract] int AddCategory(ProductCategory category);
[OperationContract] int DeleteCategory(int categoryId);
}
public class MyService : IMyService
{
public int UpdateCategory(ProductCategory category)
{
using (var ctx = new AdventureWorksEntities())
{
ctx.ProductCategories.ApplyChanges(category);
ctx.ObjectStateManager.ChangeObjectState(category, EntityState.Modified);
return ctx.SaveChanges();
}
}
public int AddCategory(ProductCategory category)
{
using (var ctx = new AdventureWorksEntities())
{
ctx.ProductCategories.ApplyChanges(category);
return ctx.SaveChanges();
}
}
public int DeleteCategory(int categoryId)
{
using (var ctx = new AdventureWorksEntities())
{
var cat = GetCategory(categoryId);
cat.MarkAsDeleted(); // 先標記再 ApplyChanges
ctx.ProductCategories.ApplyChanges(cat);
return ctx.SaveChanges();
}
}
// GetCategories/GetCategory 略...
}
private void BindData()
{
var svc = new ChannelFactory<IMyService>("BasicHttpBinding_IMyService").CreateChannel();
ListView1.DataSource = svc.GetCategories();
ListView1.DataBind();
}
protected void ListView1_ItemUpdating(object sender, ListViewUpdateEventArgs e)
{
var svc = new MyServiceClient();
var cat = svc.GetCategory((int)ListView1.DataKeys[e.ItemIndex].Value);
cat.Name = (string)e.NewValues["Name"];
svc.UpdateCategory(cat);
BindData();
}
// Insert/Delete/Cancel/Edit 類似...
| 情境 | StartTracking | 狀態標記與 ApplyChanges 順序 |
|---|---|---|
| 非 WCF (本地) | 手動呼叫 | 修改屬性前呼叫 StartTracking,再 ApplyChanges |
| WCF 跨層 | 自動 (序列化攜帶) | 先 MarkAsAdded/Modified/Deleted 再 ApplyChanges;或先 ApplyChanges 再 ChangeObjectState |
STE 解決了 N-Tier 架構下實體狀態同步難題,配合 WCF 讓伺服端極簡單地持久化離線實體圖,是 EF 4.0 企業級應用的重要特性。