为什么 SubSonic ActiveRecord 不更新我的数据?
我正在使用 SubSonic 3 ActiveRecord。我有一个名为 Users 的表,并且在 MySQL 数据库中有以下字段:
CREATE TABLE `users` (
`ID` int(10) NOT NULL auto_increment,
`Username` varchar(50) NOT NULL,
`FirstName` varchar(50) default NULL,
`LastName` varchar(50) default NULL,
`EmailAddress` varchar(100) default NULL,
`OfficePhone` varchar(25) default NULL,
`MobilePhone` varchar(25) default NULL,
`TimeZone` varchar(25) default NULL,
`LastLogin` datetime default NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=latin1
我可以毫无问题地从表中读取数据。我可以毫无问题地添加新记录,但由于某种原因无法更新现有记录。我已单步执行代码,并且 editUser 对象中包含正确的数据。
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(FormCollection result)
{
var editUser = ServiceDesk.Data.User.SingleOrDefault(x => x.ID == Convert.ToInt32(result["ID"]));
UpdateModel(editUser);
editUser.Save();
return RedirectToAction("Index", "Home");
}
这是我收到的错误:
Server Error in '/' Application.
The given key was not present in the dictionary.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
Source Error:
Line 1423:
Line 1424: if(this._dirtyColumns.Count>0)
Line 1425: _repo.Update(this,provider);
Line 1426: OnSaved();
Line 1427: }
Source File: D:\Users\Mike\Documents\Visual Studio 2008\Projects\dolphin\src\ServiceDesk.Web\Models\_Generated\ActiveRecord.cs Line: 1425
任何人都可以提供帮助吗?
这是堆栈跟踪: [KeyNotFoundException:字典中不存在给定的键。] System.ThrowHelper.ThrowKeyNotFoundException() +28 System.Collections.Generic.Dictionary2.get_Item(TKey key) +7456284 SubSonic.Extensions.Database.ToUpdateQuery(T 项,IDataProvider 提供者) +642 SubSonic.Repository.SubSonicRepository
1.Update(T 项,IDataProvider 提供者) +113 D:\Users\Mike\Documents\Visual Studio 2008\Projects\dolphin\src\ServiceDesk.Web\Models_Generate\ActiveRecord.cs 中的 ServiceDesk.Data.User.Update(IDataProvider 提供程序):1425 ServiceDesk.Data.User.Save(IDataProvider 提供程序)位于 D:\Users\Mike\Documents\Visual Studio 2008\Projects\dolphin\src\ServiceDesk.Web\Models_Generate\ActiveRecord.cs:1461 D:\Users\Mike\Documents\Visual Studio 2008\Projects\dolphin\src\ServiceDesk.Web\Models_Generate\ActiveRecord.cs 中的 ServiceDesk.Data.User.Save():1452 D:\Users\Mike\Documents\Visual Studio 2008\Projects\dolphin\src\ServiceDesk.Web\Controllers\SettingController.cs 中的 ServiceDesk.Web.Controllers.SettingController.Edit(FormCollection 结果):48 lambda_method(ExecutionScope,ControllerBase,Object[])+140 System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase控制器,Object[]参数)+17 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContextcontrollerContext,IDictionary2个参数)+178 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContextcontrollerContext,ActionDescriptoractionDescriptor,IDictionary
2个参数)+24 System.Web.Mvc.<>c__DisplayClassa.b__7() +52 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter 过滤器,ActionExecutingContext preContext,Func1 延续)+254 System.Web.Mvc.<>c__DisplayClassc.
1 过滤器, ActionDescriptor actionDescriptor, IDictionary`2 个参数) +192 System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContextcontrollerContext,字符串actionName)+399 System.Web.Mvc.Controller.ExecuteCore() +126 System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +27 System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +7 System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext)+151 System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext) +57 System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext) +7 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& CompletedSynchronously) +75
看起来问题出在这段代码中:
public static ISqlQuery ToUpdateQuery<T>(this T item, IDataProvider provider) where T : class, new()
{
Type type = typeof(T);
var settings = item.ToDictionary();
ITable tbl = provider.FindOrCreateTable<T>();
Update<T> query = new Update<T>(tbl.Provider);
if(item is IActiveRecord)
{
var ar = item as IActiveRecord;
foreach(var dirty in ar.GetDirtyColumns())
{
if(!dirty.IsPrimaryKey && !dirty.IsReadOnly)
query.Set(dirty.Name).EqualTo(settings[dirty.Name]);
}
}
dirty.Name = "FirstName" 但设置["FirstName"] 不存在,但是设置["Firstname ”]确实存在。我在数据库中的列被命名为“FirstName”、“LastName”等,但亚音速 ActiveRecord 模板将对象字段命名为“Firstname”和“Lastname”
I am playing around with SubSonic 3 ActiveRecord. I have a table called Users and I have the following fields in a MySQL database:
CREATE TABLE `users` (
`ID` int(10) NOT NULL auto_increment,
`Username` varchar(50) NOT NULL,
`FirstName` varchar(50) default NULL,
`LastName` varchar(50) default NULL,
`EmailAddress` varchar(100) default NULL,
`OfficePhone` varchar(25) default NULL,
`MobilePhone` varchar(25) default NULL,
`TimeZone` varchar(25) default NULL,
`LastLogin` datetime default NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=latin1
I can read from the table with no problems. I can add new records with no problems but I can not update existing records for some reason. I have stepped through the code and the editUser object has the correct data in it.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(FormCollection result)
{
var editUser = ServiceDesk.Data.User.SingleOrDefault(x => x.ID == Convert.ToInt32(result["ID"]));
UpdateModel(editUser);
editUser.Save();
return RedirectToAction("Index", "Home");
}
Here is the error I'm getting:
Server Error in '/' Application.
The given key was not present in the dictionary.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
Source Error:
Line 1423:
Line 1424: if(this._dirtyColumns.Count>0)
Line 1425: _repo.Update(this,provider);
Line 1426: OnSaved();
Line 1427: }
Source File: D:\Users\Mike\Documents\Visual Studio 2008\Projects\dolphin\src\ServiceDesk.Web\Models\_Generated\ActiveRecord.cs Line: 1425
Can anyone offer some assistance?
Here is the stack trace:
[KeyNotFoundException: The given key was not present in the dictionary.]
System.ThrowHelper.ThrowKeyNotFoundException() +28
System.Collections.Generic.Dictionary2.get_Item(TKey key) +7456284
1.Update(T item, IDataProvider provider) +113
SubSonic.Extensions.Database.ToUpdateQuery(T item, IDataProvider provider) +642
SubSonic.Repository.SubSonicRepository
ServiceDesk.Data.User.Update(IDataProvider provider) in D:\Users\Mike\Documents\Visual Studio 2008\Projects\dolphin\src\ServiceDesk.Web\Models_Generated\ActiveRecord.cs:1425
ServiceDesk.Data.User.Save(IDataProvider provider) in D:\Users\Mike\Documents\Visual Studio 2008\Projects\dolphin\src\ServiceDesk.Web\Models_Generated\ActiveRecord.cs:1461
ServiceDesk.Data.User.Save() in D:\Users\Mike\Documents\Visual Studio 2008\Projects\dolphin\src\ServiceDesk.Web\Models_Generated\ActiveRecord.cs:1452
ServiceDesk.Web.Controllers.SettingController.Edit(FormCollection result) in D:\Users\Mike\Documents\Visual Studio 2008\Projects\dolphin\src\ServiceDesk.Web\Controllers\SettingController.cs:48
lambda_method(ExecutionScope , ControllerBase , Object[] ) +140
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +17
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary2 parameters) +178
2 parameters) +24
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary
System.Web.Mvc.<>c__DisplayClassa.b__7() +52
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func1 continuation) +254
1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +192
System.Web.Mvc.<>c__DisplayClassc.<InvokeActionMethodWithFilters>b__9() +19
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +399
System.Web.Mvc.Controller.ExecuteCore() +126
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +27
System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +7
System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext) +151
System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext) +57
System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext) +7
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75
Looks like the problem is in this code:
public static ISqlQuery ToUpdateQuery<T>(this T item, IDataProvider provider) where T : class, new()
{
Type type = typeof(T);
var settings = item.ToDictionary();
ITable tbl = provider.FindOrCreateTable<T>();
Update<T> query = new Update<T>(tbl.Provider);
if(item is IActiveRecord)
{
var ar = item as IActiveRecord;
foreach(var dirty in ar.GetDirtyColumns())
{
if(!dirty.IsPrimaryKey && !dirty.IsReadOnly)
query.Set(dirty.Name).EqualTo(settings[dirty.Name]);
}
}
dirty.Name = "FirstName" but settings["FirstName"] doesn't exist, however settings["Firstname"] does exist. My columns in the db are named like "FirstName", "LastName", etc but subsonic ActiveRecord template named the object fields like "Firstname" and "Lastname"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我的第一个猜测是 TimeZone 是 C# 中的保留字 (System.TimeZone),虽然这确实不重要 - 这是我能想到的第一件事。关键错误可能是 SubSonic 试图查找名称为“TimeZone”且已重命名的属性 - 检查您的 Structs.cs 类/用户表以查看情况是否如此。
如果是这样,请提交错误。如果没有 - 堆栈跟踪会有所帮助。
My first guess is that TimeZone is a reserved word in C# (System.TimeZone) and while this really shouldn't matter - it's the first thing I can think of. The Key error could be that SubSonic is trying to find a property with the name "TimeZone" that has been renamed - check your Structs.cs class/User table to see if that's the case.
If so please file a bug. If not - a stack trace would help.
当尝试更新行时,我也在 3.0.0.4 版本中遇到此异常。我以前使用过 SubSonic 1.0,但这是我第一次尝试使用 v3 - 所以我可能在这个过程中忽略了一些东西。
我发现的最快的解决方法是简单地删除该行,然后直接插入它。这可能更少比仅仅更新更有效 - 但在性能不关键的上下文中可能是可以接受的。
I'm also getting this exception in the 3.0.0.4 release when trying to update a row. I have previously used SubSonic 1.0 but this is my first attempt at using v3 - so I may have overlooked something in the process..
The quickest workaround I found is to simply delete the row, then insert it straight after.. This is probably less efficient than just updating - but may be acceptable within contexts that aren't performance critical.