I'm going nuts over what should be a very simple situation. In an ASP.NET MVC 2 app (not that I think this matters), I have an edit action which takes a very small entity and makes a few changes. The key portion (outside of error handling/security) looks like this:
Todo t = Repository.GetTodoByID(todoID);
UpdateModel(t);
Repository.Save();
Todo
is the very simple, small entity with the following fields: ID
(primary key), FolderID
(foreign key), PercentComplete
, TodoText
, IsDeleted
and SaleEffortID
(foreign key). Each of these obviously corresponds to a field in the database.
When UpdateModel(t)
is called, t
does get correctly updated for all fields which have changed.
When Repository.Save()
is called, by the time the SQL is w开发者_如何学运维ritten out, FolderID
reverts back to its original value. The complete code to Repository.Save()
:
public void Save()
{
myDataContext.SubmitChanges();
}
myDataContext
is an instance of the DataContext class created by the LINQ-to-SQL designer. Nothing custom has been done to this aside from adding some common interfaces to some of the entities.
I've validated that the FolderID is getting lost before the call to Repository.Save()
by logging out the generated 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
So somewhere between UpdateModel(t)
(where I've validated in the debugger that FolderID updated) and the output of this SQL, the FolderID reverts. The other fields all save. (Well, OK, I haven't validated SaleEffortID yet, because that subsystem isn't really ready yet, but everything else saves.)
I've exhausted my own means of research on this: Does anyone know of conditions which would cause a partial entity reset (EG, something to do with long
foreign keys?), and/or how to work around this?
The only thing I can think of, is if something forces the datacontext to load the related entity (which would be Folder in this case, I think) before the call to UpdateModel.
If you try to change FolderID after the Folder entity has been loaded, it will silently fail and retain it's old value. This can be kindof annoying. I don't know if this is the case here, however as you appear positive that the values are updated by the UpdateModel call.
Normally, if the foreign key is changed before the datacontext tries to load the related entity, then the correct entity will be loaded (the one with the new key), but somehow, maybe something happens that triggers a mysterious behaviour in this case - I know it's not much to go on, but I would definitely expect this to have something to do with deferred loading of the related entity.
精彩评论