DataPortal_Create and Database Identity Field

DataPortal_Create and Database Identity Field

Old forum URL: forums.lhotka.net/forums/t/5410.aspx


Pixel posted on Tuesday, September 16, 2008

Having just upgraded to 3.5.1  from 3.0.2. I 'believe' Im experiencing a change in behaviour in the dataportal.   I'm under pressure time wise so hope someone can help......I guess the information is there in front of me but I cant see the wood from the trees!!!

Admitedly I'm using the same techniques in the new version as in 3.0.2 to call a stored procedure on an insert.  Im not using LINQ or anything...

I cant quite understand why I can't upate the objects private variables whilst in the dataportal_create function and have the calling application see them through the property get function. 

Previsouly Im sure I was able to query the output parameter and update the objects Id with the identity field.  I am getting this value back from the DB and updating the Id value but when checking it in nUnit the Id value just reverts back to the temporary one.

I'm not explaing in it too well as Im really pressured for time but here are a few code snippets.


Parts of DataPortal_Insert  (Really basic)
.
.
.
SqlParameter paramClientId =new SqlParameter("@clientId", SqlDbType
.Int);
paramClientId.Direction =
ParameterDirection
.Output;
cm.Parameters.Add(paramClientId);
cm.ExecuteNonQuery();
_clientId = (int)cm.Parameters["@clientId"
].Value;

At this point _clientId is the identity value

 

Property Value (Standard stuff)

private int _clientId;

[System.ComponentModel.
DataObjectField(true, true)]
public int ClientId
{
[System.Runtime.CompilerServices.
MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
get
{
CanReadProperty(
true);
return _clientId;
}
}



Calling code: (Test Harness)


ClientPersonalDetail
client = ClientPersonalDetail.NewClientPersonalDetail();
client.Surname =
"User";
client.Firstname = "Sample";
client.Save();
Console.WriteLine (client.ClientId);

ClientId comes back as 0!!!!


 

 

 

 

 

 

sergeyb replied on Tuesday, September 16, 2008

I think you are missing this

Client.Save().ClientID?

 

Sergey Barskiy

Principal Consultant

office: 678.405.0687 | mobile: 404.388.1899

Magenic ®

Microsoft Worldwide Partner of the Year | Custom Development Solutions, Technical Innovation

 

From: Pixel [mailto:cslanet@lhotka.net]
Sent: Tuesday, September 16, 2008 12:48 PM
To: Sergey Barskiy
Subject: [CSLA .NET] DataPortal_Create and Database Identity Field

 

Having just upgraded to 3.5.1  from 3.0.2. I 'believe' Im experiencing a change in behaviour in the dataportal.   I'm under pressure time wise so hope someone can help......I guess the information is there in front of me but I cant see the wood from the trees!!!

Admitiedly  I'm using the same techniques in the new version as in 3.0.2 to call a stored procedure on an insert.  Im not using LINQ or anything...

I cant quite understand why I can't upate the objects private variables whilst in the dataportal_create function and have the calling application see them through the property get function. 

Previsouly Im sure I was able to query the output parameter and update the objects Id with the identity field.  I am getting this value back from the DB and updating the Id value but when checking it in nUnit the Id value just reverts back to the temporary one.

I'm not explaing in it to well as Im really pressured for time but here are a few code snippets.


Parts of DataPortal_Insert  (Really basic)
.
.
.
SqlParameter paramClientId =new SqlParameter("@clientId", SqlDbType.Int);
paramClientId.Direction = ParameterDirection.Output;
cm.Parameters.Add(paramClientId);
cm.ExecuteNonQuery();
_clientId = (int)cm.Parameters["@clientId"].Value;

At this point _clientId is the identity value

 

Property Value (Standard stuff)

private int _clientId;

[System.ComponentModel.DataObjectField(true, true)]
public int ClientId
{
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
get
{
CanReadProperty(true);
return _clientId;
}
}



Calling code: (Test Harness)

ClientPersonalDetail
client = ClientPersonalDetail.NewClientPersonalDetail();
client.Surname = "User";
client.Firstname = "Sample";
client.Save();
Console.WriteLine (client.ClientId);

ClientId comes back as 0!!!!


 

 

 

 

 

 



Wbmstrmjb replied on Tuesday, September 16, 2008

sergeyb:

I think you are missing this

Client.Save().ClientID? 

Can you please explain this?  How is:

 client.Save();

client.ClientID;

any different than

client.Save().ClientID;

I am confused.  I too think that the above code should work and now am doubting my knowledge.

sergeyb replied on Tuesday, September 16, 2008

.Save method calls the server, passing it the object you are trying to save.  Server returns an updated copy of that object.  So, your DataPortal_Insert method is executed on the server side, and that is where client ID is updated.  So, you need to look at the server copy of the object which is the result of Save() function.

 

Sergey Barskiy

Principal Consultant

office: 678.405.0687 | mobile: 404.388.1899

Magenic ®

Microsoft Worldwide Partner of the Year | Custom Development Solutions, Technical Innovation

 

From: Wbmstrmjb [mailto:cslanet@lhotka.net]
Sent: Tuesday, September 16, 2008 1:16 PM
To: Sergey Barskiy
Subject: Re: [CSLA .NET] RE: DataPortal_Create and Database Identity Field

 

sergeyb:

I think you are missing this

Client.Save().ClientID? 

Can you please explain this?  How is:

 client.Save();

client.ClientID;

any different than

client.Save().ClientID;

I am confused.  I too think that the above code should work and now am doubting my knowledge.



Wbmstrmjb replied on Tuesday, September 16, 2008

sergeyb:

.Save method calls the server, passing it the object you are trying to save.  Server returns an updated copy of that object.  So, your DataPortal_Insert method is executed on the server side, and that is where client ID is updated.  So, you need to look at the server copy of the object which is the result of Save() function.

I feel like I've taken some kind of stupid pills.  Why didn't the object come back from the server?  You're saying that in his "test code", the object "client" is going to the server and staying there?  This is so not normal.  Why after a Save() can he not get the updated values of his object on the client?  CSLA has never been a one-way transport.  I am not doubting your answer, considering your position, but I am certainly doubting my understanding of it right now.

sergeyb replied on Tuesday, September 16, 2008

It is possible I am not explanting it correctly.  You should always consume the return value of Save() function and replace the original object with that value at some point.

 

Sergey Barskiy

Principal Consultant

office: 678.405.0687 | mobile: 404.388.1899

Magenic ®

Microsoft Worldwide Partner of the Year | Custom Development Solutions, Technical Innovation

 

From: Wbmstrmjb [mailto:cslanet@lhotka.net]
Sent: Tuesday, September 16, 2008 1:31 PM
To: Sergey Barskiy
Subject: Re: [CSLA .NET] RE: RE: DataPortal_Create and Database Identity Field

 

sergeyb:

.Save method calls the server, passing it the object you are trying to save.  Server returns an updated copy of that object.  So, your DataPortal_Insert method is executed on the server side, and that is where client ID is updated.  So, you need to look at the server copy of the object which is the result of Save() function.

I feel like I've taken some kind of stupid pills.  Why didn't the object come back from the server?  You're saying that in his "test code", the object "client" is going to the server and staying there?  This is so not normal.  Why after a Save() can he not get the updated values of his object on the client?  CSLA has never been a one-way transport.  I am not doubting your answer, considering your position, but I am certainly doubting my understanding of it right now.



Wbmstrmjb replied on Tuesday, September 16, 2008

sergeyb:

It is possible I am not explanting it correctly.  You should always consume the return value of Save() function and replace the original object with that value at some point.

 

All is well again with the universe!  I just realized what was going on.  Yes, Save returns the updated object, not updates the object itself.  I totally missed that part of his code.  Sorry to waste your time.

tmg4340 replied on Tuesday, September 16, 2008

No - I believe the OP made a common mistake.  Instead of saying

"client.Save();"

it should say

"client = client.Save();"

Sergey's point is that when the DP_ methods run, they return a new instance of the object.  Since the object is serialized back and forth, you must update the reference to your object on the client.

(In the case of a local DataPortal, the framework makes a clone of the object, even though the DP_ methods run in the same process.  This is done so that client code does not have to make a distinction between DataPortal locations.)

HTH

- Scott

RockfordLhotka replied on Tuesday, September 16, 2008

That is almost certainly the problem - and it is listed as one of the breaking changes from 3.0 to 3.5 - but a lot of people still miss this one.

Pixel replied on Tuesday, September 16, 2008

RockfordLhotka:
That is almost certainly the problem - and it is listed as one of the breaking changes from 3.0 to 3.5 - but a lot of people still miss this one.


Thanks Rocky.

With looming deadlines I didnt quite take the time to step back and look through the notes.

I'm glad there is a great community behind this framework.


Copyright (c) Marimer LLC