silverlight 4 的 IAsyncRepository 或 IObservableRepository + WCF 数据服务
更新2:@Enigmativity 有一个出色的答案。我已将其实现到 IObservableRepository
中。详细信息在我下面的回答中。
问题: 因此,我已经更改了大部分问题(请参阅编辑历史记录),如果有人对我的设计进行评论/验证/呕吐,我会喜欢它。 =)
所以通常我的存储库看起来像这样:
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)
}
您可以像这样使用存储库:
productRepo.GetAllFromQuery(
x => x.Products.Where(p => p.ID > 5),
y => Assert.IsTrue(y.Count > 0)); //y is a IList<Product>
你们觉得怎么样?
问候, 吉迪恩
Update 2 : @Enigmativity has a brilliant answer. I've implemented this into a IObservableRepository<T>
. Details in my answer below.
Question:
So I've changed most of the question (See edit history) I would just like it if someone commented/validated/puked on my design. =)
So typically my Repos look like this:
public interface IRepository<T> where T : class
{
T GetById(int id);
IQueryable<T> GetAll();
void InsertOnSubmit(T entity);
void DeleteOnSubmit(T entity);
int SubmitChanges();
}
But when it comes to Silverlight and WCF Data Services, it gets seriously annoying query related data with all the asynchrony. I have to load the parent entity async first and then query its child entities async.
So I came up with an IAsyncRepository
, I'd like to know if the design is ok, whether it could be improved, (and whether it makes any sense using Rx here?)
To Solve the child entities problem I plan to load all required child entities before calling the callback.
My Repo looks like:
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)
}
You could use the repo like this:
productRepo.GetAllFromQuery(
x => x.Products.Where(p => p.ID > 5),
y => Assert.IsTrue(y.Count > 0)); //y is a IList<Product>
What do you guys think?
Regards,
Gideon
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
只是一个快速、即兴的回答。
如何使用 Reactive .NET (Rx) 扩展?
然后,您可以将存储库定义为:
所有返回的可观察量都将包含单个值,
GetAll
除外,它具有零个或多个值。在 Rx 世界中,
Unit
类型是void
。这只是一种不需要定义非通用 IObservable 接口的方法。然后,您可以像这样查询:
提交可以这样完成:
这都是基于尝试使存储库方法尽可能接近原始方法,但可能值得在 Silverlight 方面重构为如下所示
:现在会好一点:
就像我说的,即兴的。 :-)
Just a quick, off the cuff answer.
How about using the Reactive Extensions for .NET (Rx)?
You could then define your repository as:
All of the returned observables would contain single values, except for
GetAll
which would have zero or more.The
Unit
type isvoid
in the Rx world. It's just a way of not needing to define a non-genericIObservable
interface.You would then query like so:
And submit could be done like this:
This is all based on trying to keep the repository methods as close as possible to the original, but it may be worth refactoring on the Silverlight side to something like this:
Submit would be a bit nicer now:
Like I said, off the cuff. :-)
太长了,无法更新问题,所以我发布了答案。
所以我像这样实现它:
一些注意事项:
GetAll()
需要TContext
,该实现将具有实体框架DataServiceContext
这将允许您执行以下操作://helpers
的方法仅调用采用数组的其他方法。加载子实体时,我只是通过这样做来急切地加载它们:
我基本上可以像这样使用它:
请告诉我是否应该在此处放置实际的实现。
任何对此的评论都会被很好地接受=)
谢谢
Too long to update the question, so I posted as an answer.
So I implemented it like this:
Some notes :
TContext
is needed forGetAll()
, the implementation will have the Entity FrameworkDataServiceContext
which will allow you to do the following://helpers
just call the other methods that take arrays.DataServiceResponse
. What I do is loop through them and return the Http Status Codes. So the ints returned for the CRUD methods are Http Status Codes.When loading child entities I just eager loaded them by doing this:
I can basically use it like this:
Do tell me if I should put up the actual implementation here.
Any comments on this would be well taken =)
Thanks