ADO.NET Data Services - распространять изменения по отслеживаемым спискам? - PullRequest
1 голос
/ 21 января 2010

Итак, вот ситуация. Я использую ADP.NET Data Services 1.5 CTP2 с Silverlight 3. Моя модель данных EF (вкратце) выглядит следующим образом:

CmsProfile
      Id
      Name

CmsEvent
      Id
      Title

CmsProfileEventLink
      Id
      ProfileId
      EventId

Так что между людьми и событиями существует множество <-> отношений. Когда я загружаю события в silverlight, я делаю это так:

private void AsyncLoadEventsKickoff()
{
    DataServiceQuery<CmsEvent> theQuery = dashboardService
        .CmsEvents
        .Expand("CmsProfileEventLinks")
        .AddQueryOption("$orderby", "Title");

    theQuery.BeginExecute(
        delegate(IAsyncResult asyncResult)
        {
            Dispatcher.BeginInvoke(
                () =>
                {
                    DataServiceQuery<CmsEvent> query = 
                        asyncResult.AsyncState as DataServiceQuery<CmsEvent>;
                    if (query != null)
                    {
                        //create a tracked DataServiceCollection from the 
                        //result of the asynchronous query.
                        events = DataServiceCollection
                            .CreateTracked<CmsEvent>(dashboardService,
                                query.EndExecute(asyncResult));

                        AsyncLoadTracker();
                    }
                }
            );
        },
        theQuery
    );
}

Вы заметите, что я не могу заставить Expand() фактически опустить следующий уровень и получить мне детали ссылки на событие. Он только скажет мне, есть ли записи о событиях или нет.

Я помещаю все события в сетку (SelectionGrid), и когда вы щелкаете по одному, я хочу загрузить ДРУГУЮ сетку (EventsGrid) с людьми, которые связаны с этим событием. Я делаю это, загружая сетку с CmsProfileEventLink объектами, а затем углубляясь в DataMemberPath до имени профиля. Теоретически, это позволяет сетке добавлять новые ссылки для меня - когда добавляется строка, я даю ей Id и устанавливаю CmsEvent для текущего события, принимаю пользовательский ввод для Profile и blammo - новая связанная запись.

В идеальном мире я могу просто установить peopleGrid.ItemsSource = EventsGrid.Selecteditem.CmsPeopleEventLinks, и все будет работать, как и ожидалось. Однако, поскольку расширение не стало таким глубоким, я не могу.

В качестве обходного пути я загрузил все CmsProfileEventLinks одинаково в переменную "links". Поэтому, когда вы выбираете событие, я делаю это (некрасиво, некрасиво), чтобы показать профили ...

private void Sync_EventsGrid()
{
    var item = SelectionGrid.SelectedItem as CmsEvent;

    if (item.CmsEventProfileLinks != null)
    {
        DataServiceCollection<CmsEventProfileLink> x = 
            DataServiceCollection
                .CreateTracked<CmsEventProfileLink>(
                     dashboardService, 
                     links.Where(p => p.CmsEvent == item));

        EventsGrid.ItemsSource = x;
    }
}

Проблема в том, что ... если изменение сделано в EventsGrid, оно НЕ распространяется на контекст ссылок, даже если они оба имеют общий контекст DataService. Чистый результат? Если вы выберете другое событие и вернетесь назад, EventsGrid НЕ покажет недавно добавленную запись. Если вы обновите приложение, заставляя его перечитывать ссылки из базы данных? это поднимает это.

Так что мне нужно что-то из следующего ...

  1. Способ сделать 2 уровня расширения записи CmsEvent на начальном загрузить, чтобы я мог просто передать его ссылки свойство для второй сетки (сохранение контекста)

  2. Лучший способ получить отфильтрованный просмотр "ссылок", которые НЕ порождают независимый контекст, который не обновление

  3. Способ уведомить "ссылки" возражать, что он должен обновить, желательно не заставляя его идти вплоть до сервера через асинхронный вызов - так как данные четко был обновлен в местном контекст.

Есть подсказки?

1 Ответ

1 голос
/ 22 октября 2010

Вы можете перебрать расширенное свойство и вызвать LoadProperty для каждого из них, чтобы раскрыть его дочерние элементы, например:

DataServiceQuery<CmsEvent> query 
                         = asyncResult.AsyncState as DataServiceQuery<CmsEvent>;
if (query != null)
{
    //create a tracked DataServiceCollection from the 
    //result of the asynchronous query.
    events = DataServiceCollection.CreateTracked<CmsEvent>(dashboardService,
                                                 query.EndExecute(asyncResult));
    AsyncLoadTracker();

    foreach(var link in events.SelectMany(e=> e.CmsProfileEventLink))
    {
         dashboardService.LoadProperty(link, "CmsPeopleEventLinks");
    }
}
...