Службы данных ADO.NET - распространять изменения по отслеживаемым спискам?

Итак, вот ситуация. Я использую 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 одинаковым образом в переменную "ссылки". Поэтому, когда вы выбираете событие, я делаю это (уродливое, уродливое, уродливое), чтобы показать профили ...

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. Способ сделать двухуровневое расширение записи CmsEvent при начальной загрузке, чтобы я мог просто передать ее свойство links во вторую сетку (с сохранением контекста)

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

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

Какие-нибудь намеки?


person Samurai Ken    schedule 21.01.2010    source источник


Ответы (1)


Вы можете перебрать расширенное свойство и вызвать 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");
    }
}
person jball    schedule 22.10.2010