Ok, Mike. Here is the pertinent code. It is a web application in C# 3.5
The form, at it's core, is a simple one. Display a list, user selects item, display details. The Form's Load event calls the method to load the list:
Code:
/// <summary>
/// Loads the groups into the list
/// This refreshes from the database
/// </summary>
private void LoadGroups()
{
try
{
// Forces a refresh from the database
ViewState.Remove(GROUPS);
lstSecurityGroup.DataSource = Groups;
lstSecurityGroup.DataTextField = "Name";
lstSecurityGroup.DataValueField = "SecurityGroupId";
lstSecurityGroup.DataBind();
if (lstSecurityGroup.Items.Count > 0)
{
lstSecurityGroup.SelectedIndex = 0;
lstSecurityGroup_SelectedIndexChanged(null, null); // Display the details for the first item
}
// Setup for group copy
cboGroupCopy.Items.Clear();
cboGroupCopy.Items.Add(new ListItem(String.Empty, "0"));
foreach (ListItem item in lstSecurityGroup.Items)
{
cboGroupCopy.Items.Add(new ListItem(item.Text, item.Value));
}
}
catch (Exception ex)
{
LogError(ex);
}
}
The DataSource for the list is a form property. The property checks ViewState for an existing collection and, if missing, loads it from the DB.
Code:
/// <summary>
/// Returns the group collection.
/// A call is made to the database only if the
/// ViewState is empty
/// </summary>
private SecurityGroupCollection Groups
{
get
{
if (ViewState[GROUPS] == null)
{
try
{
SecurityGroupCollection sGroups = new SecurityGroupCollection();
sGroups.Query.OrderBy(sGroups.Query.Name, esOrderByDirection.Ascending);
sGroups.Query.Load();
ViewState.Add(GROUPS, sGroups);
}
catch (Exception ex)
{
LogError(ex);
}
}
return (SecurityGroupCollection)ViewState[GROUPS];
}
}
When the user selects a new item in the list, the SelectedIndexChanged event displays it to the form. Inside that event is a call to this method.
Code:
/// <summary>
/// Fill the group info tab with information
/// </summary>
private void SetGroupInfo()
{
try
{
txtGroupName.Text = SelectedGroup.str.Name;
txtGroupDescription.Text = SelectedGroup.Description;
cboGroupCopy.SelectedIndex = 0;
CreatingGroup = false;
}
catch (Exception ex)
{
LogError(ex);
}
}
This method fails on the call to SelectedGroup.str.Name. I added the .str property in an attempted to find the cause of this problem. Name is already a string property so .str is not necessary. Here is the SelectedGroup property.
Code:
/// <summary>
/// Returns the SecurityGroup selected in the list
/// </summary>
private SecurityGroup SelectedGroup
{
get
{
SecurityGroup retGroup = new SecurityGroup();
try
{
retGroup = Groups.FindByPrimaryKey(Convert.ToInt32(lstSecurityGroup.SelectedValue));
}
catch (Exception ex)
{
LogError(ex);
}
return retGroup;
}
}
This property always runs successfully. A SecurityGroup object is always returned. Although all of it's DB field properties fail when called. Oddly enough, this only happens after the initial load of the page. The first call (in the form load event) works fine. Here is the error from the log.
Code:
Page: Admin/GroupAdmin.aspx
Exception Data: System.Collections.ListDictionaryInternal
Event: System.String GetSystemString(System.String)
Message: Object reference not set to an instance of an object.
Stack Trace: at EntitySpaces.Core.esEntity.GetSystemString(String columnName) at
BusinessObjects.esSecurityGroup.get_Name() in
D:\Documents and Settings\Mark\My Documents\Visual Studio 2008\Projects\DTAWeb2\DTAWeb2\Generated\SecurityGroup.cs:line 238
at BusinessObjects.esSecurityGroup.esStrings.get_Name() in
D:\Documents and Settings\Mark\My Documents\Visual Studio 2008\Projects\DTAWeb2\DTAWeb2\Generated\SecurityGroup.cs:line 340
at DTAWeb2.Admin.GroupAdmin.SetGroupInfo() in D:\Documents and Settings\Mark\My Documents\Visual Studio 2008\Projects\DTAWeb2\DTAWeb2\Admin\GroupAdmin.aspx.cs:line 402
Line 238 of the generated code is the Get.
Code:
/// <summary>
/// Maps to SECURITY_GROUP.Name
/// </summary>
virtual public System.String Name
{
get
{
return base.GetSystemString(SecurityGroupMetadata.ColumnNames.Name);
}
set
{
if(base.SetSystemString(SecurityGroupMetadata.ColumnNames.Name, value))
{
this.MarkFieldAsModified(SecurityGroupMetadata.ColumnNames.Name);
}
}
}
Line 340 is the first line of this Get.
Code:
public System.String Name
{
get
{
System.String data = entity.Name;
return (data == null) ? String.Empty : Convert.ToString(data);
}
set
{
if (value == null || value.Length == 0) entity.Name = null;
else entity.Name = Convert.ToString(value);
}
}
I do not have the ES source code, so stepping beyond "base.GetSystemString(SecurityGroupMetadata.ColumnNames.Name);" is not possible for me.
Yes, I did regenerate my classes. I was forced to because of some "OnLoad" event that was no longer valid inside all the classes. I'm sorry, I don't remember the exact delegate name that was being setup. I could probably find out if you really need to know.
Were MyGeneration templates updated? It seems wierd to me that regenerating did not create the same line. I don't remember updating my templates for ES 2008. That is to say, I already had templates for ES 2008 and did not update them when I downloaded the RC.
Thanks
Mark