views:

398

answers:

1

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 SubSonic.Extensions.Database.ToUpdateQuery(T item, IDataProvider provider) +642 SubSonic.Repository.SubSonicRepository1.Update(T item, IDataProvider provider) +113 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 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parameters) +24 System.Web.Mvc.<>c__DisplayClassa.b__7() +52 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func1 continuation) +254 System.Web.Mvc.<>c__DisplayClassc.<InvokeActionMethodWithFilters>b__9() +19 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +192 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"

A: 

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.

Rob Conery
Thanks Rob. I'll give that a try. I was just loading up the source and adding it to my project but I'll try renaming TimeZone first.
Mike Roosa
no luck. i have added the stack trace. i'll step through the code later and see if i can figure it out unless you see something else.
Mike Roosa
see above, i found the problem, now just need to correct it
Mike Roosa