我对这应该是一个非常简单的情况感到疯狂。在一个ASP.NET MVC 2应用程序中(不是我认为这很重要),我有一个编辑操作,它需要一个非常小的实体并进行一些更改。关键部分(错误处理/安全性之外)如下所示:
Todo t = Repository.GetTodoByID(todoID);
UpdateModel(t);
Repository.Save();
Todo
是一个非常简单的小型实体,包含以下字段:ID
(主键),FolderID
(外键),PercentComplete
,{{1} },TodoText
和IsDeleted
(外键)。这些中的每一个显然都对应于数据库中的一个字段。
调用SaleEffortID
后,UpdateModel(t)
会针对所有已更改的字段进行正确更新。
调用t
时,在SQL写出时,Repository.Save()
将恢复为原始值。 FolderID
的完整代码:
Repository.Save()
public void Save()
{
myDataContext.SubmitChanges();
}
是LINQ-to-SQL设计器创建的DataContext类的实例。除了向某些实体添加一些通用接口之外,没有做任何自定义。
我已经通过注销生成的SQL验证了在调用myDataContext
之前FolderID丢失了:
Repository.Save()
所以介于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
(我在调试器中验证了FolderID已更新)和此SQL的输出之间,FolderID还原。 其他字段全部保存。 (好吧,好吧,我还没有验证SaleEffortID,因为那个子系统尚未准备就绪,但其他一切都保存完毕。)
我已经用尽了自己的研究方法:有没有人知道会导致部分实体重置的条件(EG,与UpdateModel(t)
外键有关吗?),和/或如何工作在这附近?
答案 0 :(得分:1)
我唯一可以想到的是,在调用UpdateModel之前,有什么东西强迫datacontext加载相关实体(在这种情况下,我认为是文件夹)。
如果在加载Folder实体后尝试更改FolderID,它将无提示失败并保留旧值。这可能有点烦人。我不知道这是否是这种情况,但是你看似肯定的是这些值是由UpdateModel调用更新的。
通常情况下,如果在datacontext尝试加载相关实体之前更改了外键,那么将加载正确的实体(带有新密钥的实体),但不知何故,可能会发生一些触发神秘行为的事件。 case - 我知道继续下去并不多,但我绝对希望这与相关实体的延迟加载有关。