silverlight - 在我的 ViewModel 中使用 DataServiceCollection 时如何实现 "Blendability"

标签 silverlight mvvm wcf-data-services blendability

我正在考虑在我的 Silverlight 客户端中使用 oData 端点。自然地,我在做 MVVM,我希望项目很好并且“可混合”(即,在设计模式下,我必须能够干净地使用静态数据而不是 oData 端点。)

现在来解决问题。我想在我的 ViewModel 中使用 DataServiceCollection,因为它允许很好的可绑定(bind)集合,而不必担心 BeginExecute/EndExecute 等。

现在,让我们看一些代码。我的模型界面如下所示:

public interface ITasksModel
{
    IQueryable<Task> Tasks { get; }
}

该接口(interface)的 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;
        }
    }
}

以及“可混合”设计时实现:
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);
    }

我得到一个异常(exception):

Only a typed DataServiceQuery object can be supplied when calling the LoadAsync method on DataServiceCollection.



首先,如果是这样的话,为什么不把LoadAsync的入参写成DataServiceQuery呢?

其次,做我想要完成的事情的“正确”方式是什么?

最佳答案

LoadAsync 需要 DataServiceQuery 的原因是普通的 IQueryable 没有定义执行查询的异步方式。该方法采用 IQueryable 类型作为其参数的原因是,用户不必将查询对象显式转换为 DataServiceQuery(使代码更短),并且由于我们假设用户将尝试至少运行一次他们的代码,他们会立即查看错误(就像您所做的那样)。

LoadAsync 只支持异步操作,所以需要DataServiceQuery。如果您已经有了结果(无需执行异步请求),您可以调用 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 的构造函数并关闭对其的跟踪。

关于silverlight - 在我的 ViewModel 中使用 DataServiceCollection 时如何实现 "Blendability",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3029331/

相关文章:

wcf - 如何使用 EF 6 为 WCF 数据服务 (odata) 设置配置文件

visual-studio - 根据 Build Configuration 修改 WMAppManifest.xml

silverlight - 如何找出我应该从套接字读取多少?

c# - 在不关闭对话框的情况下设置 DialogResult

wcf-data-services - ADO.NET 数据服务 : Passing parameter to [WebInvoke] Method

c# - 不支持异常 : Could not convert constant 1 expression to string

.net - 为 wp7 应用程序运行测试

silverlight - System.ExecutionEngineException PropertyChanged

c# - MVVMCross如何实现ContentDialog

c# - Xamarin.Forms - 选择器选择的项目绑定(bind)没有响应