我正在考虑在Silverlight客户端中使用oData端点。当然,我正在做MVVM,我希望项目很好并且“Blendable”(即我必须能够在设计模式下干净利用静态数据而不是oData端点。)
现在问题。我想在我的ViewModels中使用DataServiceCollection,因为它允许很好的可绑定集合,而不必过分担心BeginExecute / EndExecute等。
现在,让我们看看一些代码。我的模型界面如下所示:
public interface ITasksModel
{
IQueryable<Task> Tasks { get; }
}
该接口的oData端点实现:
public class TasksModel : ITasksModel
{
Uri svcUri = new Uri("http://localhost:2404/Services/TasksDataService.svc");
TaskModelContainer _container;
public TasksModel()
{
_container = new TaskModelContainer(svcUri);
}
public IQueryable<Task> Tasks
{
get
{
return _container.TaskSet;
}
}
}
“Blendable”设计时实施:
public class DesignModeTasksModel : ITasksModel
{
private List<Task> _taskCollection = new List<Task>();
public DesignModeTasksModel()
{
_taskCollection.Add(new Task() { Id = 1, Title = "Task 1" });
_taskCollection.Add(new Task() { Id = 2, Title = "Task 2" });
_taskCollection.Add(new Task() { Id = 3, Title = "Task 3" });
}
public IQueryable<Task> Tasks
{
get {
return _taskCollection.AsQueryable();
}
}
}
但是,当我尝试在我的ViewModel构造函数中使用最后一个:
public TaskListViewModel(ITasksModel tasksModel)
{
_tasksModel = tasksModel;
_tasks = new DataServiceCollection<Task>();
_tasks.LoadAsync(_tasksModel.Tasks);
}
我得到一个例外:
在DataServiceCollection上调用LoadAsync方法时,只能提供类型化的DataServiceQuery对象。
首先,如果是这种情况,为什么不将LoadAsync的输入参数键入为DataServiceQuery?
第二,做我想要完成的事情的“正确”方式是什么?
答案 0 :(得分:1)
LoadAsync需要DataServiceQuery的原因是普通的IQueryable没有定义执行查询的异步方式。该方法以IQueryable类型作为参数的原因是,用户不必明确地将查询对象强制转换为DataServiceQuery(使代码更短),因为我们假设用户将尝试至少运行一次代码,他们会立即看到错误(正如你所做的那样)。
LoadAsync仅支持异步操作,因此需要DataServiceQuery。如果您已经有结果(无需执行异步请求),则可以调用Load方法。这是你第二个问题的答案。您可以将Load用于设计时间而将LoadAsync用于运行时,而不是为设计时和运行时调用LoadAsync。但是由于跟踪约束,您可能需要以不同的方式创建DataServiceCollection。
这样的事情:
DataServiceCollection<Task> dsc;
DataServiceQuery<Task> dsq = _tasksModel as DataServiceQuery<Task>;
if (dsq != null)
{
dsc = new DataServiceCollection<Task>();
dsc.LoadAsync(dsq);
}
else
{
dsc = new DataServiceCollection<Task>(myDataServiceContext);
dsc.Load(_tasksModel);
// Invoke the LoadAsyncCompleted handler here
}
如果在调用Load之前将DataServiceContext传递给构造函数,则将跟踪实体(就像在LoadAsync情况下一样)。如果您不需要,可以调用构造函数,该构造函数接受IEnumerable和TrackingMode并关闭它的跟踪。