Как предотвратить присоединение объекта Silverlight RIA к текстовому тексту до того, как я буду готов - PullRequest
4 голосов
/ 14 июля 2010

У меня есть приложение Silverlight 4 для простого списка 'TODO'. Проблема, с которой я столкнулся, заключается в том, что привязка данных связывает отношения с моим объектом TODO, что заставляет контекст данных RIA добавить его в список DataContext.TODOs, прежде чем я захочу его там. Я хочу относиться к объекту как к новому и отделенному, пока не буду явно готов добавить его в текстовый текст данных.


Вот как это работает: У меня есть TODO сущность, связанная с Status (отношение сущностей служб RIA).

Я создаю новый объект TODO(), который передается во всплывающее окно ChildWindow. Обратите внимание, что я не добавляю эту новую сущность в мой текст данных.

 new CreateTODOPopup(new TODO()).Show();

В DataForm в моем ChildWindow у меня есть поле со списком для Status, которое привязано к DataContext.Statuses.

Проблема в том, что действие по выбору Status из выпадающего списка фактически связывает сущность с контекстом для меня - в итоге она получает состояние EntityState.New и фактически добавляется в коллекцию DataContext.TODOs.

Это было бы хорошо, за исключением того, что теперь оно появляется в главном списке TODO в главном фрейме. Я не хочу этого, потому что это еще не было зафиксировано ChildWindow.

Как я могу решить это? Либо препятствуя присоединению объекта, либо скрывая его от каких-либо элементов управления, к которым он привязан, до тех пор, пока он не будет добавлен.

Ответы [ 4 ]

1 голос
/ 25 июля 2010

ВАЖНО: После 3 дней борьбы с ужасным состоянием расы, оказалось, что это напрямую связано с этой проблемой.По сути, вывод таков: если вы пытаетесь создать сущности, а не добавлять их в контекст данных, тогда не , если вы не хотите условий гонки и неожиданного поведения.Я почти уверен, что это ошибка служб RIA.

Что я делал:

  • Создание new TODO() и передача его на мой взгляд
  • Разрешениеинфраструктура служб RIA, чтобы связать мой TODO со всеми таблицами внешних ключей, такими как Status и AssignedTo
  • При сохранении, добавив TODO() в список, если он еще не былприсутствует в наборе сущностей DataContext.TODOs.

Что сама инфраструктура сделала:

  • Когда View устанавливает внешние ключи на объекте (через comobox), онавтоматически добавит TODO в коллекцию DataContext.TODOS.Именно так работают сущности.

Почему это плохо:

  • При навигации по моему интерфейсу происходило какое-то ужасное состояние гонки.
  • Предыдущие строки (даже те, которые существовали до запуска моего приложения) были помечены как New - иногда до 20 из них, а затем сохраняются как новые повторяющиеся строки.

Какя исправил это:

  • Всегда добавлять созданные объекты в контекст данных сразу при создании.

Вот пример кода для добавления объектов сразу при создании- без условия гонки:

for (int i = 0; i < 3; i++) 
{
    var entity = new DM.TODO();
    _todoDomainContext.TODOs.Add(entity);

    entity.TODOStatu = pendingStatus;
    entity.TODOProject = project;
    entity.TODOCompany = company;

    entity.CreateDt = DateTime.Now;

    entity.Title = "generated todo " + DateTime.Now.ToString();
    entity.Details = "12345"; 
}

Этот код НЕ работал и вызывает условия гонки - добавление объектов после того, как ограничения внешнего ключа уже установлены:

for (int i = 0; i < 3; i++) 
{
    var entity = new DM.TODO();

    entity.TODOStatu = pendingStatus;
    entity.TODOProject = project;
    entity.TODOCompany = company;

    entity.CreateDt = DateTime.Now;

    entity.Title = "generated todo " + DateTime.Now.ToString();
    entity.Details = "12345"; 

    _todoDomainContext.TODOs.Add(entity);
}
1 голос
/ 14 июля 2010

Вы должны иметь возможность получить желаемое поведение, добавив другое свойство MyProject к сущности TODO, используя частичный класс. В вашем всплывающем окне вы можете установить свойство «MyProject» вместо свойства «Project». Когда вы сохраните свой TODO, вы можете применить значение «MyProject» непосредственно к «Project». Немного обходной, но это должно дать вам поведение, которое вы хотели бы.

Кайл

1 голос
/ 15 июля 2010

Полагаю, одним из способов было бы использовать PagedCollectionView и отфильтровывать «новые» объекты - но должно быть что-то очевидное, что вы упускаете.

    // data bind list to this ICollectionView
    private PagedCollectionView _projects;
    public PagedCollectionView Projects
    {
        get
        {
            if (_projects == null)
            {
                _projects = new PagedCollectionView(_todoDomainContext.TODOProjects)
                {
                    Filter = i => {

                        DM.TODOProject proj = (DM.TODOProject)i;

                        // hide New entities
                        if (proj.EntityState == EntityState.New)
                        {
                            return false;
                        }

                        return true;
                    }
                };
            }
            return _projects;
        }
    }
0 голосов
/ 14 июля 2010

Вы пытались использовать Context.Detach для объекта, чтобы четко указать, что он не должен быть в контексте?Затем вы можете использовать Context.Attach его снова, прежде чем сохранить.

...