При каких обстоятельствах объект LINQ-to-SQL «теряет» измененное поле? - PullRequest
1 голос
/ 01 мая 2010

Я схожу с ума от того, что должно быть очень простой ситуацией. В приложении ASP.NET MVC 2 (не то, что я думаю, что это имеет значение), у меня есть действие редактирования, которое принимает очень маленькую сущность и вносит несколько изменений. Ключевая часть (вне обработки ошибок / безопасности) выглядит так:

Todo t = Repository.GetTodoByID(todoID);

UpdateModel(t);
Repository.Save();

Todo - это очень простая небольшая сущность со следующими полями: ID (первичный ключ), FolderID (внешний ключ), PercentComplete, TodoText, IsDeleted и SaleEffortID ( иностранный ключ). Каждый из них, очевидно, соответствует полю в базе данных.

Когда вызывается UpdateModel(t), t корректно обновляется для всех полей, которые изменились.

Когда вызывается Repository.Save(), к моменту написания SQL FolderID возвращается к своему первоначальному значению. Полный код Repository.Save():

public void Save()
{
    myDataContext.SubmitChanges();
}

myDataContext - это экземпляр класса DataContext, созданный конструктором LINQ-to-SQL. Ничего особенного не было сделано для этого, кроме добавления некоторых общих интерфейсов для некоторых объектов.

Я проверил, что FolderID теряется перед вызовом Repository.Save(), выйдя из сгенерированного SQL:

UPDATE [Todo].[TD_TODO]
SET 
    [TD_PercentComplete] = @p4, 
    [TD_TodoText] = @p5, 
    [TD_IsDeleted] = @p6
WHERE 
    ([TD_ID] = @p0) AND 
    ([TD_TDF_ID] = @p1) AND /* Folder ID */
    ([TD_PercentComplete] = @p2) AND 
    ([TD_TodoText] = @p3) AND 
    (NOT ([TD_IsDeleted] = 1)) AND 
    ([TD_SE_ID] IS NULL) /* SaleEffort ID */
-- @p0: Input BigInt (Size = -1; Prec = 0; Scale = 0) [5]
-- @p1: Input BigInt (Size = -1; Prec = 0; Scale = 0) [1] /* this SHOULD be 4 and in the update list */
-- @p2: Input TinyInt (Size = -1; Prec = 0; Scale = 0) [90]
-- @p3: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [changing text]
-- @p4: Input TinyInt (Size = -1; Prec = 0; Scale = 0) [0]
-- @p5: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [changing text foo]
-- @p6: Input Bit (Size = -1; Prec = 0; Scale = 0) [True]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 4.0.30319.1

Таким образом, где-то между UpdateModel(t) (где я проверял в отладчике, который обновил FolderID) и выводом этого SQL, FolderID возвращается. Все поля other сохраняются. (Хорошо, хорошо, я еще не проверил SaleEffortID, потому что эта подсистема еще не готова, но все остальное сохраняется.)

Я исчерпал свои собственные средства исследования по этому вопросу: знает ли кто-нибудь об условиях, которые могут вызвать частичный сброс сущности (например, что-то связанное с long внешними ключами?), И / или как обойти это

1 Ответ

1 голос
/ 03 мая 2010

Единственное, о чем я могу думать, - это если что-то заставляет текст данных загружать связанную сущность (я думаю, в данном случае это папка) перед вызовом UpdateModel.

Если вы попытаетесь изменить FolderID после того, как объект Folder был загружен, он молча потерпит неудачу и сохранит свое старое значение. Это может быть немного раздражающим. Я не знаю, так ли это, но вы уверены, что значения обновляются вызовом UpdateModel.

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

...