2

SilverlightクライアントでoDataエンドポイントを使用することを検討しています。当然、私はMVVMを実行しており、プロジェクトを素晴らしく「ブレンド可能」にしたいと考えています(つまり、デザインモードでは、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;
        }
    }
}

そして、「ブレンド可能な」設計時の実装:

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として入力してみませんか?

第二に、私が達成しようとしていることを行うための「適切な」方法は何ですか?

4

1 に答える 1

1

LoadAsyncがDataServiceQueryを必要とする理由は、単純なIQueryableがクエリを実行する非同期の方法を定義しないためです。メソッドがIQueryable型をパラメーターとして使用する理由は、ユーザーがクエリオブジェクトをDataServiceQueryに明示的にキャストする必要がないようにするため(コードを短くする)、ユーザーがコードを少なくとも1回実行しようとすると想定しているため、 (あなたがしたように)すぐにエラーを見てください。

LoadAsyncは非同期操作のみをサポートするため、DataServiceQueryが必要です。(非同期リクエストを実行する必要なしに)すでに結果が得られている場合は、代わりにLoadメソッドを呼び出すことができます。これが2番目の質問に対する答えです。設計時と実行時の両方で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
}

Loadを調整する前にDataServiceContextをコンストラクターに渡すと、エンティティが追跡されます(LoadAsyncの場合と同様)。必要がない場合は、IEnumerableとTrackingModeを取得するコンストラクターを呼び出して、追跡をオフにすることができます。

于 2010-06-14T15:37:49.690 に答える