Как добиться «смешиваемости» при использовании DataServiceCollection в моей ViewModel - PullRequest
2 голосов
/ 12 июня 2010

Я смотрю на использование конечных точек oData в моем клиенте Silverlight.Естественно, я делаю MVVM и хочу, чтобы проект был красивым и «смешиваемым» (т.е. я должен иметь возможность чисто использовать статические данные вместо конечных точек oData в режиме разработки.)

Теперь перейдем кпроблема.Я хотел бы использовать DataServiceCollection в моих ViewModels, поскольку он позволяет создавать красивые привязываемые коллекции, не беспокоясь о 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);
    }

Я получаю исключение:

При вызове может быть предоставлен только типизированный объект DataServiceQuery.метод LoadAsync для DataServiceCollection.

Прежде всего, если это так, почему бы не сделать тип входного параметра LoadAsync типом DataServiceQuery?

Во-вторых, каков «правильный» способ сделать то, что я пытаюсь достичь?

1 Ответ

1 голос
/ 14 июня 2010

Причина, по которой LoadAsync требует DataServiceQuery, заключается в том, что просто IQueryable не определяет асинхронный способ выполнения запроса. Причина, по которой метод принимает тип IQueryable в качестве своего параметра, заключается в том, что пользователям не нужно явно приводить объект запроса к DataServiceQuery (делает код короче), и поскольку мы предполагаем, что пользователи попытаются выполнить свой код хотя бы один раз, они немедленно увидеть ошибку (как вы сделали).

LoadAsync поддерживает только асинхронные операции, поэтому ему необходим DataServiceQuery. Если у вас уже есть результаты (без необходимости выполнения асинхронного запроса), вы можете вместо этого вызвать метод Load. Какой ответ на ваш второй вопрос. Вместо вызова LoadAsync для времени разработки и времени выполнения, вы можете использовать Load для времени разработки и 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
}

Если вы передадите DataServiceContext конструктору перед вызовом Load, сущности будут отслеживаться (как в случае LoadAsync). Если вам это не нужно, вы можете вызвать конструктор, который принимает IEnumerable и TrackingMode, и отключить отслеживание для него.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...