适用于Silverlight 4 + WCF数据服务的IAsyncRepository或IObservableRepository
更新2 :@Enigmativity有一个很好的答案。 我已将其实现为IObservableRepository
。 我的答案详情如下。
问:所以我已经改变了大部分问题(参见编辑历史)如果有人对我的设计进行了评论/validation/推测,我会喜欢它。 =)
所以通常我的Repos看起来像这样:
public interface IRepository where T : class { T GetById(int id); IQueryable GetAll(); void InsertOnSubmit(T entity); void DeleteOnSubmit(T entity); int SubmitChanges(); }
但是当谈到Silverlight和WCF数据服务时,它会使所有异步的查询相关数据变得非常烦人。 我必须首先加载父实体异步,然后查询其子实体异步。
所以我提出了一个IAsyncRepository
,我想知道设计是否正常,是否可以改进,(以及在这里使用Rx是否有意义?)
要解决子实体问题,我计划在调用回调之前加载所有必需的子实体。
我的回购看起来像:
public interface IAsyncRepository where T : class { void GetById(int id, Action callback); void GetAllFromQuery(Func<MyEntities, IQueryable> funcquery, Action<IList> callback) }
您可以像这样使用repo:
productRepo.GetAllFromQuery( x => x.Products.Where(p => p.ID > 5), y => Assert.IsTrue(y.Count > 0)); //y is a IList
你们有什么感想?
问候,吉迪恩
只是快速,脱下袖口的答案。
如何使用.NET的Reactive Extensions(Rx) ?
然后,您可以将存储库定义为:
public interface IObservableRepository where T : class { IObservable GetById(int id); IObservable GetAll(Func, IQueryable > query); IObservable InsertOnSubmit(T entity); IObservable DeleteOnSubmit(T entity); IObservable SubmitChanges(); }
所有返回的observable都将包含单个值,但GetAll
除外,它将具有零或更多。
Rx世界中的Unit
类型void
。 这只是一种不需要定义非通用IObservable
接口的方法。
然后你会这样查询:
IObservableRepository 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 where T : class { IObservable GetById(int id); IObservable GetAll(Func, IQueryable > query); IObservable Submit(T[] insertsOrUpdates); IObservable Submit(T[] insertsOrUpdates, T[] deletes); }
现在提交会更好一些:
repo.Submit(foos).Subscribe(result => { // Handle asynchronous result of submit; });
就像我说的那样,袖口。 🙂
更新问题的时间太长,所以我发布了答案。
所以我实现了这样:
public interface IObservableRepository { IObservable GetById(int id); IObservable> GetAll(Func> funcquery); IObservable SubmitInserts(IList inserts); IObservable SubmitDeletes(IList deletes); IObservable SubmitUpdates(IList updates); //helpers IObservable SubmitInsert(T entity); IObservable SubmitDelete(T entity); IObservable SubmitUpdate(T entity); }
一些说明:
-
GetAll()
需要TContext
,实现将具有Entity FrameworkDataServiceContext
,它允许您执行以下操作:var foos = repo.GetAll(ts => ts.Where(t => t.Bar == "Hello")); //ts is a DataContext passed here by GetAll();
- 标记为
//helpers
的方法只调用其他采用数组的方法。 - WCF数据服务+entity framework的CRUD函数的实际返回类型是
DataServiceResponse
。 我所做的是循环它们并返回Http状态代码。 因此,为CRUD方法返回的int是Http Status Codes。 -
加载子实体时,我只是急于加载它们:
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
请告诉我是否应该在这里提出实际的实施。
对此的任何评论都会很好=)
谢谢
- C#generics – 为什么lambda工作,简单的方法不工作?
- 扑克牌:它们应该是枚举还是结构或类?
- 无法将类型’System.Data.EntityState’隐式转换为’System.Data.Entity.EntityState’。 存在显式转换(您是否错过了演员?)
- 无法将类型为“Windows.UI.Xaml.Controls.ItemsControl”的对象强制转换为“Windows.UI.Xaml.Controls.Image”
- List.Insert是否有任何性能损失?
- 有没有办法检查鼠标何时高于标准窗口控制按钮(关闭,最小化等)?
- Nuget:在packages.config中requireReinstallation标记的目的是什么
- 从IronPython调用C#对象
- 在ListView控件中访问TextBox控件