Член 'X' был изменен, чтобы быть несовместимым с членом ассоциации 'Y' - PullRequest
16 голосов
/ 03 января 2011

Я получаю эту ошибку, если выполняю следующие действия:

  1. Изменение свойства Y объекта (связанного свойства объекта)
  2. Попытка отправить изменения
  3. На этом этапе значение Y и значение X (базовый ключ) не согласованы - LINQ to SQL, по-видимому, не синхронизирует их до тех пор, пока не будет вызван GetChangeSet.
  4. Ожидается ошибка из-за некоторыхбизнес-логика или ограничение уровня базы данных во время операции обновления.
  5. На данный момент значение Y находится в согласии с X, потому что был вызван GetChangeSet.
  6. Измените значение Y на Nothing (он же null).
  7. Вызов GetChangeSet.

Ошибка возникает на последнем шаге, поскольку значение X и исходное значение X (возвращаемое GetOriginalEntityState) различаются, а новое значениене согласен с Y?Это почему?Это ошибка в LINQ to SQL.Должно быть, потому что я не вижу того же поведения, если я изменяю Y на другое (не нулевое) значение вместо этого во время шага 5. Какой правильный способ обойти это?Я вижу несколько способов:

  1. Сбросить DataContext при возникновении ошибки и оставить UI как есть.Мне это не нравится, потому что тогда не могут быть обнаружены оптимистические конфликты изменения валюты.В новом контексте нет исходных значений, которые были заполнены одновременно с заполнением пользовательского интерфейса, поэтому, если в пользовательском интерфейсе есть какие-либо устаревшие значения, они приведут к возврату данных в базе данных.
  2. Обновите текстовый текст данных (OverwriteCurrent) и оставьте пользовательский интерфейс как есть.Мне не нравится это по той же причине, что и # 1.
  3. Обновите текстовый текст данных (OverwriteCurrent) и заново заполните пользовательский интерфейс.Мне не нравится это, потому что тогда сообщение об ошибке, только что представленное пользователю, не показывает пользователю ошибку, которую они сделали, и позволяет им исправить это.Он также отбрасывает все другие изменения, которые мог внести пользователь.
  4. Когда возникает ошибка, явно извлеките ключ для Y, который соответствует исходному значению X, и сбросьте Y, затем вызовите GetChangeSet для повторной синхронизации X(X только для чтения или приватный, поэтому я не могу сбросить его напрямую).Кажется, это работает, но похоже на взлом и может потребовать много кода для других подобных ошибок.

Есть ли лучшее решение.Об этом нужно сообщать?

Ответы [ 3 ]

0 голосов
/ 21 октября 2011

Похоже, что эта ошибка была исправлена ​​в последних версиях .NET и / или Visual Studio 2010. Код, сгенерированный для файла DBML, теперь содержит код для обновления базового значения внешнего ключа даже при установке для свойства ассоциации значения null:

    [global::System.Data.Linq.Mapping.AssociationAttribute(Name="Customer_Order", Storage="_Customer", ThisKey="fkCustomer", OtherKey="id", IsForeignKey=true)]
    public Customer Customer
    {
        get
        {
            return this._Customer.Entity;
        }
        set
        {
            Customer previousValue = this._Customer.Entity;
            if (((previousValue != value) 
                        || (this._Customer.HasLoadedOrAssignedValue == false)))
            {
                this.SendPropertyChanging();
                if ((previousValue != null))
                {
                    this._Customer.Entity = null;
                    previousValue.Orders.Remove(this);
                }
                this._Customer.Entity = value;
                if ((value != null))
                {
                    value.Orders.Add(this);
                    this._fkCustomer = value.id;
                }
                else
                {
                    this._fkCustomer = default(Nullable<int>);
                }
                this.SendPropertyChanged("Customer");
            }
        }
    }

Я думаю, что this._fkCustomer = default(Nullable<int>); не должно быть там в коде, который я тестировал, когда я первоначально опубликовал этот вопрос. Так что либо у меня неправильно настроен DBML, либо эта проблема была исправлена.

0 голосов
/ 15 мая 2013

Недавно я столкнулся с этой проблемой при использовании linq to sql, мои классы были созданы с использованием sqlmetal и отображены с использованием привязок WPF.

При отображении списка значений из таблицы, с которой у меня была ссылка на внешний ключ, я устанавливал SelectedValuePath в качестве идентификатора. Однако, когда Id был обновлен в моей записи, связанный член не был обновлен в соответствии со значением Id.

(Address.provID будет 1, а Address.Province будет нулевым)

Я обновил привязку, чтобы обновить SelectedItem, а не SelectedValuePath.

<ComboBox Name="provList" DisplayMemberPath="Code" ItemsSource="{Binding Source={x:Static list:GlobalList.ProvinceList}}" SelectedItem="{Binding Path=Provinces}" Width="75" Height="23" HorizontalAlignment="Left" Margin="5,0,0,0" VerticalAlignment="Top"/>
0 голосов
/ 21 октября 2011

Для MSDN:

Для обновлений отношений ссылка от дочернего к родителю (то есть ссылка, соответствующая внешнему ключу) считается полномочным.Ссылка в обратном направлении (то есть от родителя к потомку) является необязательной.Классы отношений (EntitySet и EntityRef) гарантируют, что двунаправленные ссылки согласованы для отношений один-ко-многим и один-к-одному.Если объектная модель не использует EntitySet или EntityRef и если имеется обратная ссылка, вы обязаны поддерживать ее в соответствии с прямой ссылкой при обновлении отношения.

Если вы обновляете обе обязательные ссылкии соответствующий внешний ключ, вы должны убедиться, что они согласны.Исключение InvalidOperationException выдается, если они не синхронизированы во время вызова SubmitChanges.Хотя изменения значения внешнего ключа достаточны для того, чтобы повлиять на обновление базовой строки, вы должны изменить ссылку, чтобы поддерживать связность графа объектов и согласованность двунаправленных связей.

http://msdn.microsoft.com/en-us/library/Bb386982(v=VS.90).aspx

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