[英]Silverlight 4 accessing WCF Data Services: BeginInvoke frustrations
[英]IAsyncRepository or IObservableRepository for silverlight 4 + WCF Data Services
更新2 :@Enigmativity有一個很好的答案。 我已將其實現為IObservableRepository<T>
。 我的答案詳情如下。
問:所以我已經改變了大部分問題(參見編輯歷史)如果有人對我的設計進行了評論/驗證/推測,我會喜歡它。 =)
所以通常我的Repos看起來像這樣:
public interface IRepository<T> where T : class
{
T GetById(int id);
IQueryable<T> GetAll();
void InsertOnSubmit(T entity);
void DeleteOnSubmit(T entity);
int SubmitChanges();
}
但是當談到Silverlight和WCF數據服務時,它會使所有異步的查詢相關數據變得非常煩人。 我必須首先加載父實體異步,然后查詢其子實體異步。
所以我提出了一個IAsyncRepository
,我想知道設計是否正常,是否可以改進,(以及在這里使用Rx是否有意義?)
要解決子實體問題,我計划在調用回調之前加載所有必需的子實體。
我的回購看起來像:
public interface IAsyncRepository<T> where T : class
{
void GetById(int id, Action<T> callback);
void GetAllFromQuery(Func<MyEntities, IQueryable<Product>> funcquery,
Action<IList<Calculator>> callback)
}
您可以像這樣使用repo:
productRepo.GetAllFromQuery(
x => x.Products.Where(p => p.ID > 5),
y => Assert.IsTrue(y.Count > 0)); //y is a IList<Product>
你們有什么感想?
問候,基甸
只是一個快速,袖手旁觀的答案。
如何使用.NET的Reactive Extensions(Rx) ?
然后,您可以將存儲庫定義為:
public interface IObservableRepository<T> where T : class
{
IObservable<T> GetById(int id);
IObservable<T> GetAll(Func<IQueryable<T>, IQueryable<T>> query);
IObservable<Unit> InsertOnSubmit(T entity);
IObservable<Unit> DeleteOnSubmit(T entity);
IObservable<int> SubmitChanges();
}
所有返回的observable都將包含單個值, GetAll
除外,它們將具有零或更多。
Rx世界中的Unit
類型void
。 這只是一種不需要定義非通用IObservable
接口的方法。
然后你會這樣查詢:
IObservableRepository<Foo> repo = ...;
var foos = repo.GetAll(ts => ts.Where(t => t.Bar == "Hello"));
foos.Subscribe(foo =>
{
// Do something asynchronously with each `Foo`.
});
提交可以這樣做:
var submit =
foos
.Select(foo => repo.InsertOnSubmit(foo)).ToArray()
.Select(s => repo.SubmitChanges());
submit.Subscribe(result =>
{
// handle the asynchronous result of submit.
});
這都是基於嘗試使存儲庫方法盡可能接近原始方法,但在Silverlight方面可能需要重構這樣的事情:
public interface IObservableRepository<T> where T : class
{
IObservable<T> GetById(int id);
IObservable<T[]> GetAll(Func<IQueryable<T>, IQueryable<T>> query);
IObservable<int> Submit(T[] insertsOrUpdates);
IObservable<int> Submit(T[] insertsOrUpdates, T[] deletes);
}
現在提交會更好一些:
repo.Submit(foos).Subscribe(result =>
{
// Handle asynchronous result of submit;
});
就像我說的,脫下袖口。 :-)
更新問題的時間太長,所以我發布了答案。
所以我實現了這樣:
public interface IObservableRepository<T, TContext>
{
IObservable<T> GetById(int id);
IObservable<IList<T>> GetAll(Func<TContext, IQueryable<T>> funcquery);
IObservable<int[]> SubmitInserts(IList<T> inserts);
IObservable<int[]> SubmitDeletes(IList<T> deletes);
IObservable<int[]> SubmitUpdates(IList<T> updates);
//helpers
IObservable<int> SubmitInsert(T entity);
IObservable<int> SubmitDelete(T entity);
IObservable<int> SubmitUpdate(T entity);
}
一些說明:
GetAll()
需要TContext
,實現將具有Entity Framework DataServiceContext
,它允許您執行以下操作:
var foos = repo.GetAll(ts => ts.Where(t => t.Bar == "Hello")); //ts is a DataContext passed here by GetAll();
//helpers
的方法只調用其他采用數組的方法。 DataServiceResponse
。 我所做的是循環它們並返回Http狀態代碼。 因此,為CRUD方法返回的int是Http狀態代碼。 加載子實體時,我只是急於加載它們:
context.Products.Expand("Child").Expand("Child2");
我基本上可以像這樣使用它:
productRepo.GetById(3).Subscribe(x => /* Do something with product x*/ );
productRepo.SubmitUpdate(product)
.Subscribe(r => /*return code should be 204 (http) 201 for insert */);
//same for insert and delete
請告訴我是否應該在這里提出實際的實施。
對此的任何評論都將很好地=)
謝謝
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.