Selfservicing Entity Constructor and non identity primary keys

Posts   
 
    
kkemp
User
Posts: 23
Joined: 21-Sep-2003
# Posted on: 19-Jan-2009 06:25:44   

I tried searching around to see if/why this is an expected behavior but I couldn't come up with anything. If you have an entity which has a primary key that is not an identity field and you attempt to load a row that doesn't exist via the constructor you get back an object which has the primary keys set but when you call .Save() they are not inserted. For example:


_answer = new NarrativeEntity(NarrativeQuestionId.Value, LeaEntity.EntityId);
//_answer. NarrativeQuestionId and _answer.EntityId both are set now
_answer.Save();  // Save does not insert values for either primary keys thus failing

The work around is to simply set the primary key fields if IsNew is true. I would be OK if the new object was actually empty but the fact that it contains the data for the primary keys threw me off.

-Keith

Walaa avatar
Walaa
Support Team
Posts: 14993
Joined: 21-Aug-2005
# Posted on: 19-Jan-2009 10:14:14   

Which runtime library version are you using? Do you set any fields other than the PK?, try to set a field and see if the save works or not?

kkemp
User
Posts: 23
Joined: 21-Sep-2003
# Posted on: 19-Jan-2009 22:53:03   

Walaa wrote:

Which runtime library version are you using? Do you set any fields other than the PK?, try to set a field and see if the save works or not?

I'm using 2.6.8.819. I dug into this a bit deeper and my analysis is the issue is simply that the IsChanged property of the primary key fields does not get set to true and thus they are not inserted. Which makes sense for example when a primary key is an identity field. As a developer though it was a bit strange to see the IDs being set to the proper values but not being inserted. I think it would make more sense if in the constructor when IsNew is true if the values were reset so it's clear that they need to be manually set. Just my two cents. Probably falls under the a lot of extra generated code for not that big of an issue.

-Keith

Test code:

long questionId = 1;
long entityId = 1;

NarrativeEntity narrative = new NarrativeEntity(questionId, entityId);

Response.Write(string.Format("IsNew:{0}<br />", narrative.IsNew));
Response.Write(string.Format("NarrativeQuestionId:{0}<br />", narrative.NarrativeQuestionId));
Response.Write(string.Format("EntityId:{0}<br />", narrative.EntityId));
try
{
    Response.Write(string.Format("Save return value:{0}<br />", narrative.Save()));
    Response.Write("Save succeeded?<br />");
    Response.Write(string.Format("IsNew:{0}<br />", narrative.IsNew));
    narrative.Delete();
}
catch (Exception ex)
{
    Response.Write(string.Format("Save failed:{0}<br />", ex.Message));
}

Response.Write("<br />");
narrative = new NarrativeEntity(questionId, entityId);
try
{
    narrative.NarrativeText = "test";
    Response.Write(string.Format("IsNew:{0}<br />", narrative.IsNew));
    Response.Write(string.Format("NarrativeQuestionId:{0}<br />", narrative.NarrativeQuestionId));
    Response.Write(string.Format("EntityId:{0}<br />", narrative.EntityId));
    Response.Write(string.Format("NarrativeQuestionId IsChanged:{0}<br />", narrative.Fields["NarrativeQuestionId"].IsChanged));
    Response.Write(string.Format("EntityId IsChanged:{0}<br />", narrative.Fields["EntityId"].IsChanged));
    narrative.Save();
    Response.Write("Save succeeded after setting text.<br />");
    narrative.Delete();
}
catch (Exception ex)
{
    Response.Write(string.Format("Save failed after setting text:{0}<br />", ex.Message));
}

Response.Write("<br />");
narrative = new NarrativeEntity(questionId, entityId);
try
{
    narrative.NarrativeQuestionId = questionId;
    Response.Write(string.Format("NarrativeQuestionId IsChanged:{0}<br />", narrative.Fields["NarrativeQuestionId"].IsChanged));
    narrative.EntityId = entityId;
    narrative.NarrativeText = "test";
    narrative.Save();
    Response.Write("Save succeeded after setting Ids and text.<br />");
    Response.Write(string.Format("IsNew:{0}<br />", narrative.IsNew));
    narrative.Delete();
}
catch (Exception ex)
{
    Response.Write(string.Format("Save failed after after setting Ids:{0}<br />", ex.Message));
}

narrative = new NarrativeEntity(questionId, entityId);
try
{
    narrative.NarrativeText = "test";
    narrative.Fields["NarrativeQuestionId"].IsChanged = true;
    narrative.Fields["EntityId"].IsChanged = true;
    narrative.Save();
    Response.Write("Save succeeded after setting text and IsChanged to true for Ids.<br />");
    narrative.Delete();
}
catch (Exception ex)
{
    Response.Write(string.Format("Save failed after after setting text and IsChanged to true for Ids:{0}<br />", ex.Message));
}

Output:


IsNew:True
NarrativeQuestionId:1
EntityId:1
Save return value:True
Save succeeded?
IsNew:True

IsNew:True
NarrativeQuestionId:1
EntityId:1
NarrativeQuestionId IsChanged:False
EntityId IsChanged:False
Save failed after setting text:An exception was caught during the execution of an action query: Cannot insert the value NULL into column 'NarrativeQuestionId', table 'eSPv3Dev.dbo.SectionNarrative'; 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.

NarrativeQuestionId IsChanged:True
Save succeeded after setting Ids and text.
IsNew:False

Save succeeded after setting text and IsChanged to true for Ids.

Walaa avatar
Walaa
Support Team
Posts: 14993
Joined: 21-Aug-2005
# Posted on: 20-Jan-2009 09:30:33   

Just my two cents. Probably falls under the a lot of extra generated code for not that big of an issue.

Yeah exactly, normally PKs passed in the CTor are only used for fetching the entity, as opposed to setting them explicitly.

btw, you need to use the latest runtime library available, as you are using an outdated build.

kkemp
User
Posts: 23
Joined: 21-Sep-2003
# Posted on: 20-Jan-2009 09:48:31   

Walaa wrote:

btw, you need to use the latest runtime library available, as you are using an outdated build.

Thanks! I had just assumed that there was not any new releases since June 2008 as the latest new items is from then. Looks like I must not be subscribed to the newsletter either.

It sure would be nice if LLBLgen 3 would automatically check for updates simple_smile

-Keith