Linq-to-Sql SubmitChanges не обновляет поля ... почему? - PullRequest
6 голосов
/ 22 декабря 2008

Я вчера опубликовал этот вопрос , который привел меня к обнаружению огромной проблемы!

У меня есть десятичный столбец в моей базе данных, который называется Units, каждый раз, когда я устанавливаю значение столбца в NON ZERO, и SubmitChanges обновляет столбец с новым значением. Если я пытаюсь установить значение столбца в ноль, SubmitChanges не обновляет столбец.

data.Units = this.ReadProperty<decimal>(UnitsProperty);
data.UnitPrice = this.ReadProperty<decimal>(UnitPriceProperty);
data.Price = this.ReadProperty<decimal>(PriceProperty);

Я посмотрел журнал DataContext и вижу, что поле со значением ZERO не включено в запрос. Даже если я попытаюсь жестко закодировать изменение, Linq игнорирует его.

data.Units = 0;
data.UnitPrice = 0;
data.Price = 0;

Само собой разумеется, это убивает меня! Есть идеи, почему это происходит?

Решение

Я выяснил свою проблему с помощью SO-сообщества. Моя проблема была вызвана тем фактом, что когда я создавал объект для присоединения, значение столбца по умолчанию было установлено равным нулю, поэтому, когда он пытался присвоить значение нулю ... LinqToSql говорит: "эй ... ничего не изменилось Я не обновляю значение.

То, что я делаю сейчас ... просто, чтобы заставить его работать, следующее:

ctx.DataContext.InvoiceItems.Attach(data, true);

Кажется, это заставляет все значения записывать себя в базу данных. Пока это работает.

Ответы [ 6 ]

3 голосов
/ 22 декабря 2008

Я попытался воспроизвести это с помощью следующего кода, но для меня это работает.

using (DataClasses1DataContext ctx = new DataClasses1DataContext())
{
    var obj = ctx.DecimalColumnTables.First();
    Debug.Assert(obj.B != 0);
    obj.B = 0;
    ctx.SubmitChanges();
}

Так что я думаю, что в вашем домене должно быть что-то особенное, что вызывает это. Я предлагаю вам создать такое простое воспроизведение с вашей моделью домена и посмотреть, что произойдет.

LINQ to SQL игнорирует обновления текущего значения, поэтому, если поле уже было равно нулю, вы можете не увидеть никаких обновлений.

Выкл .: OR / M, который вы используете: LINQ to SQL . LINQ - это имя возможности запросов в .NET, но LINQ не определяет и не реализует логику обновления. Таким образом, проблема связана с LINQ to SQL, а не с LINQ.

2 голосов
/ 23 декабря 2008

Еще немного информации ... Я понял свою проблему ... это скорее недостаток понимания LinqToSql ... где я делаю:

private void Child_Update(Invoice parent)
{
      using (var ctx = Csla.Data.ContextManager
           .GetManager(Database.ApplicationConnection, false))
      {
           var data = new Gimli.Data.InvoiceItem()
           {
                InvoiceItemId = ReadProperty(InvoiceItemIdProperty)
           };

           ctx.DataContext.InvoiceItems.Attach(data);

           if (this.IsSelfDirty)
           {
                // Update properties
           }
     }
}

Я думал, что это загрузит исходные значения ... в результате создается новый объект со значениями по умолчанию ... пустые значения, например 0 для десятичных чисел, Guid.Empty для уникальных идентификаторов и т. Д.

Таким образом, когда он обновляет свойства, он видит Единицы уже как 0 и устанавливает его в ноль. Что ж, LinqToSql не распознает это как изменение, поэтому не обновляет поле. Так что я должен был сделать следующее:

ctx.DataContext.InvoiceItems.Attach(data, true);

Теперь все изменения генерируются в операторе обновления независимо от того, есть ли это изменение или нет. Это работает ... кажется немного хакерским!

2 голосов
/ 22 декабря 2008

Я выяснил свою проблему с помощью SO сообщества. Моя проблема была вызвана тем фактом, что когда я создавал объект для присоединения, значение столбца по умолчанию было установлено равным нулю, поэтому, когда он пытался присвоить значение нулю ... LinqToSql говорит: "эй ... ничего не изменилось, поэтому Я не обновляю значение.

То, что я делаю сейчас ... просто чтобы заставить это работать, следующее:

ctx.DataContext.InvoiceItems.Attach(data, true);

Это, кажется, заставляет все значения записывать себя в базу данных. Пока это работает.

2 голосов
/ 22 декабря 2008

Очевидный вопрос, но вы уверены, что столбец сопоставлен в файле dbml / mapping?

Также - это вычисляемый столбец? (т.е. цена => единицы * цена за единицу)

1 голос
/ 11 декабря 2012

Правильный ответ, как многие указали, использует специальную перегрузку Attach, которая принимает логический параметр, чтобы считать его измененным (допустите ошибку при использовании другой перегрузки, и она просто не будет работать):

ctx.DataContext.InvoiceItems.Attach(data, true);

Обратите внимание, что вам все еще может понадобиться столбец «Версия» в таблице типа «отметка времени».

0 голосов
/ 22 июля 2009

У меня была эта проблема, и все предложения, которые я видел, не применимы или не работают.

Но я обнаружил, что совершил очень простую ошибку!

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

После нескольких часов царапин на голове я заметил, что мой метод Set обновлял приватный член, а не публичное свойство, т.е. this._Walking = value;

Все, что мне нужно было сделать, это изменить это на следующее. Ходьба = значение; и все заработало!

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