KeyNotFoundException on DataAccessAdapter.SaveEntity()

Posts   
 
    
peschkaj
User
Posts: 30
Joined: 21-Sep-2006
# Posted on: 21-Sep-2006 19:43:37   

I am running LLBLGenPro version 2.0.0.0 Final Released on September 8th, 2006

When I attempt to save a new Account into the database using the code generated with Adapter and Two Classes model, I running into an System.Collections.Generic.KeyNotFoundException before the DataAccessAdapter even connects to the database. There have been no changes to the database since the code was generated.

Let me know what additional information I can supply.

Thanks,

Jeremiah

Here is the code in question:


MyAccountEntity _account = CreateNewAccount ();
MyCompanyEntity _company = CreateCompany (ref _account);
MyUserEntity _user = CreateUser (ref _account, ref _company);
_adapter.SaveEntity (_account);  // <-- This line is throwing the exception

private MyUserEntity CreateUser (ref MyAccountEntity Account, ref MyCompanyEntity Company)
{
    MyUserEntity _user = (MyUserEntity) Company.Users.AddNew ();
    _user.FirstName = UserFirstName.Text.Trim ();
    _user.LastName = UserLastName.Text.Trim ();
    _user.UserName = UserUsername.Text.Trim ();
    _user.PlainTextPassword = UserPasswordFirst.Text.Trim ();
    _user.PlainTextPasswordConfirm = UserPasswordConfirmation.Text.Trim ();

    _user.Account = Account;

    // Assign user to a default Admin role
    Account.AccountAdmin = _user;

    MyEmailAddressEntity _emailAddress = (MyEmailAddressEntity) _user.EmailAddresses.AddNew ();
    _emailAddress.EmailAddress = UserEmailAddress.Text.Trim ();

    return _user;
}

private MyCompanyEntity CreateCompany (ref MyAccountEntity Account)
{
    MyCompanyEntity _company = (MyCompanyEntity) Account.Companies.AddNew ();
    _company.Name = CompanyName.Text.Trim ();

    return _company;
}

private MyAccountEntity CreateNewAccount ()
{
    MyAccountEntity _account = new MyAccountEntity ();
    _account.Name = AccountName.Text.Trim ();
    _account.Url = AccountUrl.Text.Trim ();

    return _account;
}
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 21-Sep-2006 20:27:56   

Please paste the stacktrace.

Frans Bouma | Lead developer LLBLGen Pro
peschkaj
User
Posts: 30
Joined: 21-Sep-2006
# Posted on: 21-Sep-2006 20:33:59   

at System.ThrowHelper.ThrowKeyNotFoundException() at System.Collections.Generic.Dictionary2.get_Item(TKey key) at SD.LLBLGen.Pro.ORMSupportClasses.DynamicQueryEngineBase.CreateInsertDQ(IEntityFieldCore[] fields, IFieldPersistenceInfo[] fieldsPersistenceInfo, IDbConnection connectionToUse) at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.CreateInsertDQ(IEntity2 entityToSave, IFieldPersistenceInfo[] persistenceInfoObjects) at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.PersistQueue(List1 queueToPersist, Boolean insertActions) at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.SaveEntity(IEntity2 entityToSave, Boolean refetchAfterSave, IPredicateExpression updateRestriction, Boolean recurse) at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.SaveEntity(IEntity2 entityToSave, Boolean refetchAfterSave) at SignUp_Default.Page_Load(Object sender, EventArgs e) in c:\Inetpub\wwwroot\SignUp\Default.aspx.cs:line 38

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 21-Sep-2006 21:02:01   

Could you check if the DBSpecific assembly is up to date in your application's bin folder? It looks like the DBGeneric project is more recent than the dbspecific one.

Frans Bouma | Lead developer LLBLGen Pro
peschkaj
User
Posts: 30
Joined: 21-Sep-2006
# Posted on: 21-Sep-2006 22:40:19   

Even after ensuring that both projects are in sync, I'm still getting the same error message. I regenerated the code in LLBLGen Pro, just to make sure, cleaned the solution, and then rebuilt the web project before debugging.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 21-Sep-2006 22:58:15   

Ok, so the dll's in the webapp's bin folder are indeed the latest? Sorry for nagging onto this, but your error is typically caused by an old dbspecific dll used with a newer dbgeneric dll.

Could you elaborate a bit about the entities saved, are these in an inheritance hierarchy? Can you save other entities without a problem?

Frans Bouma | Lead developer LLBLGen Pro
peschkaj
User
Posts: 30
Joined: 21-Sep-2006
# Posted on: 21-Sep-2006 23:21:22   

This error is occurring both when I attempt to save a single entity, and when I attempt to save an entity as part of an inheritance hierarchy. So far I have only attempted to save an Account entity on its own, and an Account, Company, and User as part of a hierarchy.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 22-Sep-2006 00:03:16   

It's caused by the inheritance related code I think. What I'd like to know is the exact table structure and hierarchy so I can try to reproduce it.

code of CreateInsertDQ:


public IActionQuery CreateInsertDQ(IEntityFieldCore[] fields, IFieldPersistenceInfo[] fieldsPersistenceInfo, IDbConnection connectionToUse)
{
    TraceHelper.WriteLineIf(DynamicQueryEngineBase.Switch.TraceInfo, "CreateInsertDQ", "Method Enter");

    if(fields == null)
    {
        throw new ArgumentNullException("fields", "fields can't be null.");
    }
    if(fieldsPersistenceInfo == null)
    {
        throw new ArgumentNullException("fieldsPersistenceInfo", "fieldsPersistenceInfo can't be null.");
    }
    if((fields.Length <= 0) || (fieldsPersistenceInfo.Length <= 0))
    {
        throw new ArgumentException("No fields to insert or not enough persistence info objects passed", "fields");
    }
    EntityFieldPersistenceInfoList targetFieldInfos = new EntityFieldPersistenceInfoList(fields, fieldsPersistenceInfo);
    IActionQuery toReturn = null;
    Dictionary<IEntityFieldCore, IDataParameter> fieldToParameter = new Dictionary<IEntityFieldCore,IDataParameter>();
    if(targetFieldInfos.Count>0)
    {
        // multiple targets, use a BatchActionQuery
        BatchActionQuery batchQuery = new BatchActionQuery();
        foreach(TargetEntityFieldPersistenceInfoBucket bucket in targetFieldInfos)
        {
            IActionQuery query = CreateSingleTargetInsertDQ(bucket.Fields, bucket.FieldsPersistenceInfo, connectionToUse, ref fieldToParameter);
            foreach(IEntityFieldCore field in bucket.Fields)
            {
                if(field.LinkedSuperTypeField!=null)
                {
                    ParameterParameterRelation paramParamLink = new ParameterParameterRelation(
                            fieldToParameter[field.LinkedSuperTypeField], fieldToParameter[field]);
                    query.ParameterParameterRelations.Add(paramParamLink);
                }
            }
            batchQuery.AddActionQuery(query);
        }

        toReturn = batchQuery;
    }
    else
    {
        toReturn = CreateSingleTargetInsertDQ(fields, fieldsPersistenceInfo, connectionToUse, ref fieldToParameter);
    }

    TraceHelper.WriteLineIf(DynamicQueryEngineBase.Switch.TraceInfo, "CreateInsertDQ", "Method Exit");
    return toReturn;
}

Where you can see that the dictionary used is about fields and parameters (related to eachother).

also, as this is DQE specific probably, what's the database type exactly and which DQE are you using (in case of oracle for example) ?

Frans Bouma | Lead developer LLBLGen Pro
peschkaj
User
Posts: 30
Joined: 21-Sep-2006
# Posted on: 22-Sep-2006 13:14:55   

The database is SQL Server 2005. My template bindings are in this order:

SD.TemplateBindings.SqlServerSpecific.NET20 SD.TemplateBindings.SharedTemplates.NET20 SD.TemplateBindings.SharedTemplates.BackwardsCompatability.NET20

As far as the inheritance goes, everything inherits from BaseItem. A user belongs to a company and to an account. An account can have an Account Admin, however the ID is set to null by default. Normally there is a Versions table as well, however I did not include that because it isn't strictly necessary for this. Version can simply be set to 1 for the purposes of this situation.

Here are the tables, I generated the create scripts directly from SQL Server and removed references to tables that aren't included:

Base Item:


/****** Object:  Table [Items].[BaseItem]   Script Date: 09/22/2006 07:02:48 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [Items].[BaseItem](
    [BaseItemID] [int] IDENTITY(1,1) NOT NULL,
    [RecordVersion] [int] NOT NULL,
    [ParentID] [int] NULL,
    [ParentRecordVersion] [int] NULL,
    [CreatedByID] [int] NOT NULL,
    [CreatedByRecordVersion] [int] NOT NULL,
    [CreationDate] [datetime] NOT NULL CONSTRAINT [DF_BaseItem_CreationDate]  DEFAULT (getdate()),
    [ModifiedByID] [int] NULL,
    [ModifiedByRecordVersion] [int] NULL,
    [ModificationDate] [datetime] NULL,
    [DeletedByID] [int] NULL,
    [DeletedByRecordVersion] [int] NULL,
    [DeletionDate] [datetime] NULL,
    [Type] [varchar](255) COLLATE Latin1_General_CI_AI NULL,
    [Name] [nvarchar](255) COLLATE Latin1_General_CI_AI NULL,
    [Notes] [ntext] COLLATE Latin1_General_CI_AI NULL,
    [CustomFields] [ntext] COLLATE Latin1_General_CI_AI NULL,
    [LockVersion] [timestamp] NULL,
 CONSTRAINT [PK_BaseItem] PRIMARY KEY CLUSTERED 
(
    [BaseItemID] ASC,
    [RecordVersion] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Unique Identifier for this record.' , @level0type=N'SCHEMA',@level0name=N'Items', @level1type=N'TABLE',@level1name=N'BaseItem', @level2type=N'COLUMN',@level2name=N'BaseItemID'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The version of this Record.' , @level0type=N'SCHEMA',@level0name=N'Items', @level1type=N'TABLE',@level1name=N'BaseItem', @level2type=N'COLUMN',@level2name=N'RecordVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The User who created this record.' , @level0type=N'SCHEMA',@level0name=N'Items', @level1type=N'TABLE',@level1name=N'BaseItem', @level2type=N'COLUMN',@level2name=N'CreatedByID'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The Record Version of the User who created this record.' , @level0type=N'SCHEMA',@level0name=N'Items', @level1type=N'TABLE',@level1name=N'BaseItem', @level2type=N'COLUMN',@level2name=N'CreatedByRecordVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The Date and Time that this record was created.' , @level0type=N'SCHEMA',@level0name=N'Items', @level1type=N'TABLE',@level1name=N'BaseItem', @level2type=N'COLUMN',@level2name=N'CreationDate'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The User who modified this record.' , @level0type=N'SCHEMA',@level0name=N'Items', @level1type=N'TABLE',@level1name=N'BaseItem', @level2type=N'COLUMN',@level2name=N'ModifiedByID'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The Record Version of the User who modified this record.' , @level0type=N'SCHEMA',@level0name=N'Items', @level1type=N'TABLE',@level1name=N'BaseItem', @level2type=N'COLUMN',@level2name=N'ModifiedByRecordVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The Date and Time that this record was modified.' , @level0type=N'SCHEMA',@level0name=N'Items', @level1type=N'TABLE',@level1name=N'BaseItem', @level2type=N'COLUMN',@level2name=N'ModificationDate'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The User who marked this record for deletion.' , @level0type=N'SCHEMA',@level0name=N'Items', @level1type=N'TABLE',@level1name=N'BaseItem', @level2type=N'COLUMN',@level2name=N'DeletedByID'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The Record Version of the User who marked this record for deletion.' , @level0type=N'SCHEMA',@level0name=N'Items', @level1type=N'TABLE',@level1name=N'BaseItem', @level2type=N'COLUMN',@level2name=N'DeletedByRecordVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The Date and Time that this record was marked for deletion.' , @level0type=N'SCHEMA',@level0name=N'Items', @level1type=N'TABLE',@level1name=N'BaseItem', @level2type=N'COLUMN',@level2name=N'DeletionDate'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The data type of this record.' , @level0type=N'SCHEMA',@level0name=N'Items', @level1type=N'TABLE',@level1name=N'BaseItem', @level2type=N'COLUMN',@level2name=N'Type'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'A moderately unique, human readable, identifier for this record.' , @level0type=N'SCHEMA',@level0name=N'Items', @level1type=N'TABLE',@level1name=N'BaseItem', @level2type=N'COLUMN',@level2name=N'Name'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Detailed notes and description of this record.' , @level0type=N'SCHEMA',@level0name=N'Items', @level1type=N'TABLE',@level1name=N'BaseItem', @level2type=N'COLUMN',@level2name=N'Notes'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'User defined data fields and form configuration.  Reserved for future use.' , @level0type=N'SCHEMA',@level0name=N'Items', @level1type=N'TABLE',@level1name=N'BaseItem', @level2type=N'COLUMN',@level2name=N'CustomFields'
GO
ALTER TABLE [Items].[BaseItem]  WITH CHECK ADD  CONSTRAINT [FK_BaseItem_BaseItem_Parent] FOREIGN KEY([ParentID], [ParentRecordVersion])
REFERENCES [Items].[BaseItem] ([BaseItemID], [RecordVersion])
GO
ALTER TABLE [Items].[BaseItem] CHECK CONSTRAINT [FK_BaseItem_BaseItem_Parent]
GO
ALTER TABLE [Items].[BaseItem]  WITH CHECK ADD  CONSTRAINT [FK_BaseItem_Users_Created_By] FOREIGN KEY([CreatedByID], [CreatedByRecordVersion])
REFERENCES [Accounts].[User] ([BaseItemID], [BaseItemRecordVersion])
GO
ALTER TABLE [Items].[BaseItem] CHECK CONSTRAINT [FK_BaseItem_Users_Created_By]
GO
ALTER TABLE [Items].[BaseItem]  WITH CHECK ADD  CONSTRAINT [FK_BaseItem_Users_Deleted_By] FOREIGN KEY([DeletedByID], [DeletedByRecordVersion])
REFERENCES [Accounts].[User] ([BaseItemID], [BaseItemRecordVersion])
GO
ALTER TABLE [Items].[BaseItem] CHECK CONSTRAINT [FK_BaseItem_Users_Deleted_By]
GO
ALTER TABLE [Items].[BaseItem]  WITH CHECK ADD  CONSTRAINT [FK_BaseItem_Users_Modified_By] FOREIGN KEY([ModifiedByID], [ModifiedByRecordVersion])
REFERENCES [Accounts].[User] ([BaseItemID], [BaseItemRecordVersion])
GO
ALTER TABLE [Items].[BaseItem] CHECK CONSTRAINT [FK_BaseItem_Users_Modified_By]
GO

Account:


/****** Object:  Table [Accounts].[Account] Script Date: 09/22/2006 07:03:08 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [Accounts].[Account](
    [BaseItemID] [int] NOT NULL,
    [BaseItemRecordVersion] [int] NOT NULL,
    [URL][nvarchar](255) COLLATE Latin1_General_CI_AI NULL,
    [AccountAdminID] [int] NULL,
    [AccountAdminRecordVersion] [int] NULL,
 CONSTRAINT [PK_Account] PRIMARY KEY CLUSTERED 
(
    [BaseItemID] ASC,
    [BaseItemRecordVersion] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'ID of BaseItem record containing basic details for this Account' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'Account', @level2type=N'COLUMN',@level2name=N'BaseItemID'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Record Version of BaseItem record containing basic details for this Account' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'Account', @level2type=N'COLUMN',@level2name=N'BaseItemRecordVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Login URL for this account' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'Account', @level2type=N'COLUMN',@level2name=N'URL'
GO
ALTER TABLE [Accounts].[Account]  WITH CHECK ADD  CONSTRAINT [FK_Account_BaseItem] FOREIGN KEY([BaseItemID], [BaseItemRecordVersion])
REFERENCES [Items].[BaseItem] ([BaseItemID], [RecordVersion])
GO
ALTER TABLE [Accounts].[Account] CHECK CONSTRAINT [FK_Account_BaseItem]
GO
ALTER TABLE [Accounts].[Account]  WITH CHECK ADD  CONSTRAINT [FK_Account_User] FOREIGN KEY([AccountAdminID], [AccountAdminRecordVersion])
REFERENCES [Accounts].[User] ([BaseItemID], [BaseItemRecordVersion])
GO
ALTER TABLE [Accounts].[Account] CHECK CONSTRAINT [FK_Account_User]

User:


****** Object:  Table [Accounts].[User] Script Date: 09/22/2006 07:03:15 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [Accounts].[User](
    [BaseItemID] [int] NOT NULL,
    [BaseItemRecordVersion] [int] NOT NULL,
    [AccountID] [int] NOT NULL,
    [AccountRecordVersion] [int] NOT NULL,
    [CompanyID] [int] NOT NULL,
    [CompanyRecordVersion] [int] NOT NULL,
    [DepartmentID] [int] NULL,
    [DepartmentRecordVersion] [int] NULL,
    [Title] [nvarchar](255) COLLATE Latin1_General_CI_AI NULL,
    [FirstName] [nvarchar](255) COLLATE Latin1_General_CI_AI NOT NULL,
    [MiddleName] [nvarchar](255) COLLATE Latin1_General_CI_AI NULL,
    [LastName] [nvarchar](255) COLLATE Latin1_General_CI_AI NOT NULL,
    [PasswordSalt] [varchar](255) COLLATE Latin1_General_CI_AI NOT NULL,
    [PasswordHash] [varchar](255) COLLATE Latin1_General_CI_AI NOT NULL,
    [UserName] [nvarchar](255) COLLATE Latin1_General_CI_AI NOT NULL,
    [PrimaryEmailAddressID] [int] NOT NULL,
    [PrimaryEmailAddressRecordVersion] [int] NOT NULL,
    [AddressID] [int] NULL,
    [AddressRecordVersion] [int] NULL,
    [DefaultRate] [money] NULL,
    [PrimaryPhoneNumber] [nvarchar](50) COLLATE Latin1_General_CI_AI NULL,
    [MobilePhoneNumber] [nvarchar](50) COLLATE Latin1_General_CI_AI NULL,
    [FaxNumber] [nvarchar](50) COLLATE Latin1_General_CI_AI NULL,
 CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED 
(
    [BaseItemID] ASC,
    [BaseItemRecordVersion] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY],
 CONSTRAINT [IX_User_EmailAddress] UNIQUE NONCLUSTERED 
(
    [PrimaryEmailAddressID] ASC,
    [PrimaryEmailAddressRecordVersion] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY],
 CONSTRAINT [IX_User_UserName] UNIQUE NONCLUSTERED 
(
    [UserName] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'ID of BaseItem record containing basic details for this User' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'User', @level2type=N'COLUMN',@level2name=N'BaseItemID'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'RecordVersion of BaseItem record containing basic details for this User' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'User', @level2type=N'COLUMN',@level2name=N'BaseItemRecordVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Account this user belongs to' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'User', @level2type=N'COLUMN',@level2name=N'AccountID'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Record Version of the Account this user belongs to' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'User', @level2type=N'COLUMN',@level2name=N'AccountRecordVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Company this user belongs to' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'User', @level2type=N'COLUMN',@level2name=N'CompanyID'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Record Version of the Company this user belongs to' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'User', @level2type=N'COLUMN',@level2name=N'CompanyRecordVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Department this user belongs to' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'User', @level2type=N'COLUMN',@level2name=N'DepartmentID'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Record Version of the Department this user belongs to' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'User', @level2type=N'COLUMN',@level2name=N'DepartmentRecordVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'User''s first name' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'User', @level2type=N'COLUMN',@level2name=N'FirstName'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'User''s middle name' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'User', @level2type=N'COLUMN',@level2name=N'MiddleName'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'User''s last name' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'User', @level2type=N'COLUMN',@level2name=N'LastName'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Salt used to generate and compare user password' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'User', @level2type=N'COLUMN',@level2name=N'PasswordSalt'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Hashed password' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'User', @level2type=N'COLUMN',@level2name=N'PasswordHash'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Shortened name used to for application access' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'User', @level2type=N'COLUMN',@level2name=N'UserName'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'User''s primary email address' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'User', @level2type=N'COLUMN',@level2name=N'PrimaryEmailAddressID'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Record Version of the User''s primary email address' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'User', @level2type=N'COLUMN',@level2name=N'PrimaryEmailAddressRecordVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'User''s primary physical address' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'User', @level2type=N'COLUMN',@level2name=N'AddressID'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Record Version of the User''s primary physical address' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'User', @level2type=N'COLUMN',@level2name=N'AddressRecordVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Default rate for this person across all projects.' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'User', @level2type=N'COLUMN',@level2name=N'DefaultRate'
GO
ALTER TABLE [Accounts].[User]  WITH CHECK ADD  CONSTRAINT [FK_Users_Account] FOREIGN KEY([AccountID], [AccountRecordVersion])
REFERENCES [Accounts].[Account] ([BaseItemID], [BaseItemRecordVersion])
GO
ALTER TABLE [Accounts].[User] CHECK CONSTRAINT [FK_Users_Account]
GO
ALTER TABLE [Accounts].[User] CHECK CONSTRAINT [FK_Users_Address]
GO
ALTER TABLE [Accounts].[User]  WITH CHECK ADD  CONSTRAINT [FK_Users_BaseItem] FOREIGN KEY([BaseItemID], [BaseItemRecordVersion])
REFERENCES [Items].[BaseItem] ([BaseItemID], [RecordVersion])
GO
ALTER TABLE [Accounts].[User] CHECK CONSTRAINT [FK_Users_BaseItem]
GO
ALTER TABLE [Accounts].[User]  WITH CHECK ADD  CONSTRAINT [FK_Users_Company] FOREIGN KEY([CompanyID], [CompanyRecordVersion])
REFERENCES [Accounts].[Company] ([BaseItemID], [BaseItemRecordVersion])
GO
ALTER TABLE [Accounts].[User] CHECK CONSTRAINT [FK_Users_Company]
GO

Company:


/****** Object:  Table [Accounts].[Company] Script Date: 09/22/2006 07:03:40 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [Accounts].[Company](
    [BaseItemID] [int] NOT NULL,
    [BaseItemRecordVersion] [int] NOT NULL,
    [AccountID] [int] NOT NULL,
    [AccountRecordVersion] [int] NOT NULL,
 CONSTRAINT [PK_Company] PRIMARY KEY CLUSTERED 
(
    [BaseItemID] ASC,
    [BaseItemRecordVersion] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'ID of BaseItem record containing basic details for this Company' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'Company', @level2type=N'COLUMN',@level2name=N'BaseItemID'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Record Version of BaseItem record containing basic details for this Company' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'Company', @level2type=N'COLUMN',@level2name=N'BaseItemRecordVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The Account this Company belongs to' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'Company', @level2type=N'COLUMN',@level2name=N'AccountID'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Record Version of the Account this Company belongs to' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'Company', @level2type=N'COLUMN',@level2name=N'AccountRecordVersion'
GO
ALTER TABLE [Accounts].[Company]  WITH CHECK ADD  CONSTRAINT [FK_Company_Account] FOREIGN KEY([AccountID], [AccountRecordVersion])
REFERENCES [Accounts].[Account] ([BaseItemID], [BaseItemRecordVersion])
GO
ALTER TABLE [Accounts].[Company] CHECK CONSTRAINT [FK_Company_Account]
GO
ALTER TABLE [Accounts].[Company]  WITH CHECK ADD  CONSTRAINT [FK_Company_BaseItem] FOREIGN KEY([BaseItemID], [BaseItemRecordVersion])
REFERENCES [Items].[BaseItem] ([BaseItemID], [RecordVersion])
GO
ALTER TABLE [Accounts].[Company] CHECK CONSTRAINT [FK_Company_BaseItem]

peschkaj
User
Posts: 30
Joined: 21-Sep-2006
# Posted on: 22-Sep-2006 14:32:47   

I neglected to include the EmailAddress table.

Additionally, there is some additional code in place in the MyUserEntity class to generate the password salt and hashed password.


USE [WatchDog30]
GO
/****** Object:  Table [Accounts].[EmailAddress]    Script Date: 09/22/2006 08:29:07 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [Accounts].[EmailAddress](
    [BaseItemID] [int] NOT NULL,
    [BaseItemRecordVersion] [int] NOT NULL,
    [UserID] [int] NOT NULL,
    [UserRecordVersion] [int] NOT NULL,
    [EmailAddress] [nvarchar](255) COLLATE Latin1_General_CI_AI NOT NULL,
 CONSTRAINT [PK_EmailAddress] PRIMARY KEY CLUSTERED 
(
    [BaseItemID] ASC,
    [BaseItemRecordVersion] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY],
 CONSTRAINT [IX_EmailAddress] UNIQUE NONCLUSTERED 
(
    [EmailAddress] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'ID of BaseItem record containing basic details for this Email Address' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'EmailAddress', @level2type=N'COLUMN',@level2name=N'BaseItemID'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Record Version of BaseItem record containing basic details for this Email Address' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'EmailAddress', @level2type=N'COLUMN',@level2name=N'BaseItemRecordVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The User this Email Address is associated with.' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'EmailAddress', @level2type=N'COLUMN',@level2name=N'UserID'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The Record Version of the User this Email Address is associated with.' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'EmailAddress', @level2type=N'COLUMN',@level2name=N'UserRecordVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Email Address' , @level0type=N'SCHEMA',@level0name=N'Accounts', @level1type=N'TABLE',@level1name=N'EmailAddress', @level2type=N'COLUMN',@level2name=N'EmailAddress'
GO
ALTER TABLE [Accounts].[EmailAddress]  WITH CHECK ADD  CONSTRAINT [FK_EmailAddress_BaseItem] FOREIGN KEY([BaseItemID], [BaseItemRecordVersion])
REFERENCES [Items].[BaseItem] ([BaseItemID], [RecordVersion])
GO
ALTER TABLE [Accounts].[EmailAddress] CHECK CONSTRAINT [FK_EmailAddress_BaseItem]
GO
ALTER TABLE [Accounts].[EmailAddress]  WITH CHECK ADD  CONSTRAINT [FK_EmailAddress_Users] FOREIGN KEY([UserID], [UserRecordVersion])
REFERENCES [Accounts].[User] ([BaseItemID], [BaseItemRecordVersion])
GO
ALTER TABLE [Accounts].[EmailAddress] CHECK CONSTRAINT [FK_EmailAddress_Users]

peschkaj
User
Posts: 30
Joined: 21-Sep-2006
# Posted on: 22-Sep-2006 16:01:59   

If I split out the calls to save the Account, then the Company and finally the User, both the Account and Company entities save correctly, however the User save does not complete and throws this error:

at System.ThrowHelper.ThrowKeyNotFoundException() at System.Collections.Generic.Dictionary2.get_Item(TKey key) at SD.LLBLGen.Pro.ORMSupportClasses.DynamicQueryEngineBase.CreateInsertDQ(IEntityFieldCore[] fields, IFieldPersistenceInfo[] fieldsPersistenceInfo, IDbConnection connectionToUse) at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.CreateInsertDQ(IEntity2 entityToSave, IFieldPersistenceInfo[] persistenceInfoObjects) at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.PersistQueue(List1 queueToPersist, Boolean insertActions) at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.SaveEntity(IEntity2 entityToSave, Boolean refetchAfterSave, IPredicateExpression updateRestriction, Boolean recurse) at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.SaveEntity(IEntity2 entityToSave, Boolean refetchAfterSave) at SignUp_Default.Page_Load(Object sender, EventArgs e) in c:\Inetpub\wwwroot\SignUp\Default.aspx.cs:line 52

At one point, earlier in troubleshooting this bug, the exception I received stated that the key AccountAdminId could not be found.

peschkaj
User
Posts: 30
Joined: 21-Sep-2006
# Posted on: 22-Sep-2006 16:13:33   

The MyUserEntity class has 2 additional private members - PlainTextPassword and PlainTextPasswordConfirm as well as two public properties for those private fields. Could this cause any problems?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 22-Sep-2006 16:18:25   

I've a bit of a problem creating the schema, I still get fk errors, but I hope these are because they're already there.

Looking at the model, I have to say: you're better off with an associated BaseItem than with a basetype BaseItem. The reason is that the db activity will have to join BaseItem a lot with every query. Inheritance in relation to entities shouldn't be overused, especially not like this, as you're not saving anything, because an associated entity with the data now located in the baseitem entity also doesn't give you any redundant data/code.

Ok, back to the problem at hand: so it's the user entity. Now, as I don't want to waste eachother's time: you said earlier that you've added code to the userentity class. Please run this test for me:

  • disable that code
  • create a user instance, just the user, no account/company entities associated
  • save the user.

Does that work?

If so, enable the code you added, rerun the test.

I'll see if I can repro it with a simple user insert, though it doesn't really looks different to me from our own inheritance database/testcode.

peschkaj wrote:

The MyUserEntity class has 2 additional private members - PlainTextPassword and PlainTextPasswordConfirm as well as two public properties for those private fields. Could this cause any problems?

Depends on how you added these. If you've added them to the base entity with this.Fields.Expand()... YES, that's the problem. If they're just private member variables, then no, they're not the problem.

(edit): When you add custom entityfields, and they're not having an expression set, the persistence info is missing, which means that they're not in the persistenceinfo array, hence the error.

Frans Bouma | Lead developer LLBLGen Pro
peschkaj
User
Posts: 30
Joined: 21-Sep-2006
# Posted on: 22-Sep-2006 16:41:11   

MyUserEntity _user = new MyUserEntity();
_user.FirstName = "Test";
_user.LastName = "User";
_user.UserName = "TestUser";
_user.PasswordHash = "abcd";
_user.PasswordSalt = "1234";
    
DataAccessAdapter _adapter = new DataAccessAdapter();
_adapter.SaveEntity (_user);

I double checked and removed the additional public properties and private members. However, this still generates the KeyNotFoundException.

System.Collections.Generic.KeyNotFoundException was unhandled Message="The given key was not present in the dictionary." Source="mscorlib" StackTrace: at System.ThrowHelper.ThrowKeyNotFoundException() at System.Collections.Generic.Dictionary2.get_Item(TKey key) at SD.LLBLGen.Pro.ORMSupportClasses.DynamicQueryEngineBase.CreateInsertDQ(IEntityFieldCore[] fields, IFieldPersistenceInfo[] fieldsPersistenceInfo, IDbConnection connectionToUse) at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.CreateInsertDQ(IEntity2 entityToSave, IFieldPersistenceInfo[] persistenceInfoObjects) at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.PersistQueue(List1 queueToPersist, Boolean insertActions) at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.SaveEntity(IEntity2 entityToSave, Boolean refetchAfterSave, IPredicateExpression updateRestriction, Boolean recurse) at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.SaveEntity(IEntity2 entityToSave) at TestSaveUser.Program.Main(String[] args) in C:\Projects\WatchDog30\TestSaveUser\Program.cs:line 22 at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 22-Sep-2006 16:51:42   

Ok, then it's something else. I'll run your code here and see what's the problem.

(edit) I also get the exception. Looking into it.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 22-Sep-2006 17:19:16   

Ok, the problem is this: BaseItem has a 2-field PK: BaseItemId and RecordVersion

BaseItemId is an identityfield, RecordVersion isn't.

When you save a user, llblgen pro recognizes 2 different entities to save and first will save the BaseItem fields. As NO fields are changed, it will generate: INSERT INTO [BugTest].[Items].[BaseItem] DEFAULT VALUES;SELECT @BaseItemId_BaseItemEntity=SCOPE_IDENTITY()

This gives 1 field-parameter for this query. Then comes the insert for the user table. As User has also 2 fields as PK, BaseItemId and BaseItemRecordVersion, it will have these two fields linked to the supertype's fields which are in the same entity (as they're inherited.

LLBLGenPro will now create parameter-parameter links for the user insert query so the user insert query's parameters for the two PK fields will borrow their value from the values for the PK of the supertype.

However, the supertype's parameter's lack the PK field RecordVersion as it didn't get a value.

This is not intercepted by LLBLGen Pro because there is an identityfield in the PK, and it then always proceeds with creating the query.

When I set the RecordVersion field of User to a value, it will create a proper query, though your example of course crashes because CreatedById is null, but that's not important: it then comes up with a proper query.

So set the recordversion property to a value prior to saving, that will fix it.

Normally: no-one will run into this, because either there's no pk value set (when no identity /sequenced pk) and the engine will report this, OR the pk is set, OR the pk is an identity field.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 15
Joined: 30-Nov-2006
# Posted on: 30-Nov-2006 19:20:02   

I too am experiencing the same problem, with the same stack trace.

[KeyNotFoundException: The given key was not present in the dictionary.]
   System.ThrowHelper.ThrowKeyNotFoundException() +28
   System.Collections.Generic.Dictionary`2.get_Item(TKey key) +2635988
   SD.LLBLGen.Pro.ORMSupportClasses.DynamicQueryEngineBase.CreateInsertDQ(IEntityFieldCore[] fields, IFieldPersistenceInfo[] fieldsPersistenceInfo, IDbConnection connectionToUse) +377
   SD.LLBLGen.Pro.ORMSupportClasses.DaoBase.AddNew(IEntityFields fields, ITransaction containingTransaction) +202
   Lateral.Content.EntityClasses.TemplatesEntity.InsertEntity() in c:\Documents and Settings\jonlee\My Documents\Visual Studio 2005\WebSites\Levi CMS Phase 1\App_Code\EntityClasses\TemplatesEntity.cs:503
   SD.LLBLGen.Pro.ORMSupportClasses.DaoBase.PersistQueue(List`1 queueToPersist, Boolean insertActions, ITransaction transactionToUse) +577
   SD.LLBLGen.Pro.ORMSupportClasses.EntityBase.Save(IPredicate updateRestriction, Boolean recurse) +670
   Lateral.Content.EntityClasses.TemplateVersionsEntity.Save(IPredicate updateRestriction, Boolean recurse) in c:\Documents and Settings\jonlee\My Documents\Visual Studio 2005\WebSites\Levi CMS Phase 1\App_Code\EntityClasses\TemplateVersionsEntity.cs:185
   SD.LLBLGen.Pro.ORMSupportClasses.EntityBase.Save(Boolean recurse) +114

I have the following tables / entities

SectionContent, which is the subclass of Templates, with a PK-FK relation on the ID PK of each table.

TemplateVersions with a composite primary key, TemplateID and TempVersionID.

TemplateID is a foreign key with the ID key in the Templates table (which in turn is a foreign key in the SectionContent table).

Finally, Templates has a (nullable) field LatestVersionId, which together with the ID field, is a foreign key on the primary key of TemplateVersions, mapping to TemplateID and TempVersionID. This way there is a 1-1 mapping from a Templates table row to its latest version in the TemplateVersions table.

I create a new TemplateVersions entity, set it's parent Template to a new Templates entity, set some values and do a Save(true), which is when I get this exception. I have tried stripping it down so that the LatestVersionId remains null, but still no joy.

i.e., something like this:

            TemplateVersionsEntity template = new TemplateVersionsEntity();
            TemplatesEntity templateBase = new TemplatesEntity();
            //templateBase.LatestVersion = template;
            template.Template = templateBase;
            template.Save(true);

Any idea why I am getting this error? What does it mean?

Best regards,

Luke

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 01-Dec-2006 10:28:04   

You have a cycle in your model: Templates point to TemplateVersions and TemplateVersions points to Templates. This isn't saveable without storing NULL in a field. LLBLGen Pro doesn't support cycles in models. So you've to explicitly set LastVersionId to NULL using templates.SetNewFieldValue((int)TemplatesFieldIndex.LastVersionId, null); then save it, then save it again by setting hte lastversionid.

though it's HIGHLY recommended that you rework your model to avoid the cycle. Relational models with cycles aren't practical, as they depend on eachother so can't efficiently save rows in both tables.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 15
Joined: 30-Nov-2006
# Posted on: 04-Dec-2006 11:03:44   

I found the cause of the error. I added SectionContent as a base class, setting the PK-FK relationship, but forgot to clear the Identity attribute of the Template PK. I updated the database, refreshed the schema and then ran the program again. This time I got an error saying that it couldn't insert a NULL into the Template ID field. This is a problem I've come up against more than once, and seems to be due to LLBLGen Pro not properly refreshing changes to the identity attribute of PKs. I removed the table from the project and added it back again and all is now fine.

It is now working with the cycle, although obviously it cannot set the LatestVersionID field in the Template table without having saved the TemplateVersion, which can't be saved before the Template, which is a cycle. LLBL will save without errors, but the LatestVersionID will always be NULL, although it can be set straight afterwards.

I will look into adding a new table, say TemplateLatestVersions, with a TemplateID and TemplateVersionID in it. Then I could remove the LatestVersionID field from the Templates table, and remove the cycle. Adding/updating the entry in the TemplateLatestVersions table at the end would be analagous to setting the LatestVersionID seperately at the end in the current data model, but would allow it all to be encapsulated into one, rather than two Save() operations, which is cleaner. Similarly for deleting a template.

Many thanks for your advice.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 04-Dec-2006 12:23:59   

lukejackson wrote:

I found the cause of the error. I added SectionContent as a base class, setting the PK-FK relationship, but forgot to clear the Identity attribute of the Template PK. I updated the database, refreshed the schema and then ran the program again. This time I got an error saying that it couldn't insert a NULL into the Template ID field. This is a problem I've come up against more than once, and seems to be due to LLBLGen Pro not properly refreshing changes to the identity attribute of PKs. I removed the table from the project and added it back again and all is now fine.

Could you elaborate a bit more about LLBLGen Pro not refreshing the identity flag on fields? As that works here without a hickup so if you could reproduce this with a couple of steps I could use these to track down the issue you experienced and try to fix it in that case.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 15
Joined: 30-Nov-2006
# Posted on: 07-Dec-2006 11:18:20   

Otis wrote:

Could you elaborate a bit more about LLBLGen Pro not refreshing the identity flag on fields? As that works here without a hickup so if you could reproduce this with a couple of steps I could use these to track down the issue you experienced and try to fix it in that case.

I will try to figure out how to reproduce this exactly for you, but I'm working to a tight deadline at the moment so it might have to wait a little bit.

From memory, I set up a superclass/subclass by setting a PK/FK relation on the tables' ID. However, both accidentally had the identity flag set. I then cleared the identity flag on the subtype, but LLBL still wouldn't save the value of the PK into the FK. I checked to see that the identity flag had been cleared in the field in the generated code, which it had, yet nevertheless it would try to set the field to NULL (or just not set it, not sure what the underlying SQL was doing). Perhaps then the problem is that the PK-FK relation changed as a result and that wasn't being updated? I'm not sure, although removing and readding the table from LLBL fixed it.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 07-Dec-2006 14:42:53   

When you have time, it would be helpful to post a code snippet and the corresponding generated SQL statement.

Thanks.

Posts: 15
Joined: 30-Nov-2006
# Posted on: 19-Dec-2006 19:02:18   

I've come across the error again. This time I fixed it without having to remove and re-add the table.

It seems like when I turned off the identity flag of a PK in the database and regenerated, LLBL still showed "SCOPE_IDENTITY()" in the Sequence Name property of the field, even though it correctly showed the Identity flag as false.

I turned the identity flag on and off again in LLBL (not touching the database) which cleared the Sequence Name, and the error went away.

I am working to a crazy deadline at the moment so can't really spend too much time troubleshooting this issue. However, i do have a copy of the project file with the inconsistent setting if you want it.

bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 20-Dec-2006 01:15:00   

Go ahead and send it to support at llblgen dot com. Thanks for the assistance.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 03-Jan-2007 11:39:53   

It's an issue which has to be fixed with an architectural change in the designer, and by doing this to v2.0, it can cause problems when a person with an older build of v2.0 loads a project saved with a newer build which has this fix. The fix is postponed till v2.1

Frans Bouma | Lead developer LLBLGen Pro