Foreign Key constraint exception creating sub-type

Posts   
 
    
Posts: 16
Joined: 22-Mar-2006
# Posted on: 26-Apr-2006 09:16:24   

I've just started using LLBLGen Pro (and I like it a lot), and I have what's probably a real newbie question (I looked and couldn't find the answer in the documentation or on the forum):

I'm using the Self Servicing, two class scenario with the 3/31/06 version of LLBLGen Pro with VisualStudio 2005 and SQL Server 2005.

I have an entity named Company which is a sub-type of the entity Party. In both Party and Company the primary key consists of two fields, Id and Version. (in Company I named these IdCompany and VersionCompany). I have defined a Foreign Key relationship FK_Party_Company_Party that matches Id with IdCompany and Version with VersionCompany. I think this is all set up correctly because LLBLGen Pro recognizes the sub-type relationship between these entities.

Both Id and IdCompany have SQLServer properties Identity=True, Identity seed=1, Identity increment=1

It's easy to create a PartyEntity:

PartyEntity party = new PartyEntity();
party.Version = 1;
party.Save();

But when I try to create a CompanyEntity:

CompanyEntity company = new CompanyEntity();
company.Version = 1;
company.VersionCompany = 1;
company.Save();

I get an exception: An exception was caught during the execution of an action query: The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Party_Company_Party". The conflict occurred in database "Test1", table "dbo.Party". The statement has been terminated.. Check InnerException, QueryExecuted and Parameters of this exception to examine the cause of this exception.

I used SQL Server Profiler to see the SQL that was being executed when I tried to save a CompanyEntity:

declare @p3 int set @p3=26 exec sp_executesql N'INSERT INTO [dbo].[Party] ([Version]) VALUES (@Version);SELECT @Id=SCOPE_IDENTITY()',N'@Id int output,@Version smallint',@Id=@p3 output,@Version=1 select @p3

declare @p3 int set @p3=NULL exec sp_executesql N'INSERT INTO [dbo].[Company] ([VersionCompany]) VALUES (@VersionCompany);SELECT @IdCompany=SCOPE_IDENTITY()',N'@IdCompany int output,@VersionCompany smallint',@IdCompany=@p3 output,@VersionCompany=1 select @p3

What is it that I need to do to create a CompanyEntity?

Thank you!

Wayne

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 26-Apr-2006 09:34:04   

I think the IdCompany should not be an Identity field, as it might try to insert a value that's with the Company version doesn't match a similar combination in the Party table.

Posts: 16
Joined: 22-Mar-2006
# Posted on: 26-Apr-2006 20:26:01   

Hi Walaa,

Thank you for your extremely quick response to my question! Your suggestion sounds good, and I gave it a try.

I changed the IdCompany field in the Company table to not be an identity, and re-ran the code. Now I get a different exception: "An exception was caught during the execution of an action query: Cannot insert the value NULL into column 'IdCompany', table 'Test1.dbo.Company'; column does not allow nulls. INSERT fails. The statement has been terminated.. Check InnerException, QueryExecuted and Parameters of this exception to examine the cause of this exception."

I again used SQL Server Profile to look at the generated SQL and as expected, it's the same as it was last time.

I'm not sure how to get around the new error. Since IdCompany is part of the primary key it must be specified as "not null".

I didn't think I should set IdCompany, as I want SQL Server to pick the Id. But just as a test, I added the line of code

 company.IdCompany = 77;

but when I run it I get an ORMFieldIsReadonlyException "The field 'IdCompany' is read-only and can't be changed."

I'm open to suggestions on what else I should do.

Is there some kind of a "cookbook" or "how to" documentation somewhere that would explain how to do things like this? The "How do I..." section in the documentation is great, but the examples mostly show what to do with LLBLGen Pro, not what to do with other programs like SQL Server (or whatever database you're using.) What would help me a lot would be some step-by-step description that would say "set this field to be an identity, set this other field to not be an identity, etc, etc."

Thanks!

Wayne Vucenic No Bugs Software Ruby and C# Agile Contract Programming in Silicon Valley. Domain Driven Designs.

Posts: 16
Joined: 22-Mar-2006
# Posted on: 26-Apr-2006 23:29:07   

Hi Walaa,

OOPS...MY MISTAKE! I changed the IdCompany field in SQL Server, but I didn't change it in LLBLGen Pro. I just now changed it in LLBLGen Pro, re-generated the code, and tried it. It now works fine.

Thank you very much!!! Sorry about my mistake in making the change.

I'd still be interested in knowing if there's some sort of "cookbook" where I can find out how to do things like this.

Thanks!!!

Wayne

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 27-Apr-2006 07:58:22   

Generally speaking you have:

1- LLBLGen Pro documentation manual. 2- Our Forums and Helpdesk. 3- There is also a book featuring LLBLGen Pro http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=5259 You may also find its link in our home page www.llblgen.com

Good Luck

Posts: 16
Joined: 22-Mar-2006
# Posted on: 27-Apr-2006 08:11:45   

Hi Walaa,

Now that I'm following your advice,

CompanyEntity company = new CompanyEntity();
company.Version = 1;
company.VersionCompany = 1;
company.Save();

will successfully write a new CompanyEntity to the database. But doing

CompanyEntity company = new CompanyEntity();
bool b = company.Save();

will not write an entity to the database. But what confuses me is that no exception is thrown, and the company.Save() call sets b to true. The documentation says that the return value is "true if Save succeeded, false otherwise". I'm confused why this returns true if the write didn't occur. How can I detect that the write failed?

Thanks,

Wayne

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 27-Apr-2006 08:21:39   

That write didn't fail, coz it didn't exist in the first place, Save only tries to write to the data base if the entity is Dirty (has some changed fields).

to know if an Entity is dirty or not inspect the Entity.IsDirty flag, and to know if a field has changed or not inspect the Field.IsChanged flag.

Posts: 16
Joined: 22-Mar-2006
# Posted on: 27-Apr-2006 18:57:08   

Thanks for the explanation!

May I suggest that it might be clearer if the documentation for this method was changed from

"true if Save succeeded, false otherwise"

to something like

"true if all changed fields successfully written, false otherwise"

Wayne