Updatable Primary Key problem


Author
Message
Aaron Young
Aaron Young
StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)
Group: StrataFrame Users
Posts: 277, Visits: 1.1K
I want to set my own value for primary keys but the BO.Save() method doesn't write the primary key back to the database.

For example, I have an Int32 primary key called "CustomerID" and I set the value in SetDefaultValues() and the value is unique. I call BO.Add() which sets the value of CustomerID. I check the value of BO.CustomerID and it is correctly set to a valid value. However, when I do BO.Save() the CustomerID field is not written back to the SQL database (I can see this in SQL Profiler).

I have tried setting PrimaryKeyIsUpdatable to true but I guess I haven't done it correctly as Save() never writes the primary key.

Can anyone help?

Thanks in advance.

Aaron Young
Aaron Young
StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)
Group: StrataFrame Users
Posts: 277, Visits: 1.1K
Oops! Just noticed that PrimaryKeyIsAutoIncremented was set to true. Making it false and PrimaryKeyIsUpdatable to true works.

Sorry for the wasted post.

Aaron Young
Aaron Young
StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)StrataFrame User (439 reputation)
Group: StrataFrame Users
Posts: 277, Visits: 1.1K
It's me again Smile

My BO is mapped to the Database Deployment Toolkit. Is there a table or primary key property in the DDT that sets the BO to PrimaryKeyIsAutoIncremented to true and PrimaryKeyIsUpdatable = false? The DDT field property does not have auto incrementing enabled and "Primary Key is Updatable" is false. The table properties "Automated Primary Key Index Creation on Structure Saves" is true.

Just wondering if my DDT is wrong as I would ideally like all my BOs to default to PrimaryKeyIsAutoIncremented to false and PrimaryKeyIsUpdatable = true.

Thanks

Bill Cunnien
Bill Cunnien
StrataFrame VIP (1.1K reputation)StrataFrame VIP (1.1K reputation)StrataFrame VIP (1.1K reputation)StrataFrame VIP (1.1K reputation)StrataFrame VIP (1.1K reputation)StrataFrame VIP (1.1K reputation)StrataFrame VIP (1.1K reputation)StrataFrame VIP (1.1K reputation)StrataFrame VIP (1.1K reputation)
Group: Forum Members
Posts: 785, Visits: 3.6K
Hi Aaron!

I won't be able to help you with the DDT thing.  I was wondering of you could enlighten me a bit, though.  It seems odd to me that anyone would want to make a primary key updateable (an exception would be one-time data migration, I suppose).  Could you provide a real-world example where this type of thing is the best solution for data storage and retrieval?  I use primary keys everywhere...not a one is updateable.

Thanks for helping my curiosity!
Bill

Paul Chase
Paul Chase
Advanced StrataFrame User (580 reputation)Advanced StrataFrame User (580 reputation)Advanced StrataFrame User (580 reputation)Advanced StrataFrame User (580 reputation)Advanced StrataFrame User (580 reputation)Advanced StrataFrame User (580 reputation)Advanced StrataFrame User (580 reputation)Advanced StrataFrame User (580 reputation)Advanced StrataFrame User (580 reputation)
Group: Forum Members
Posts: 414, Visits: 2.8K
Bill,

They added the PrimaryKeyUpdatable to remove the primekey from the update statement that is generated by the datalayer.

So with PrimaryKeyUpdatable set to false when a record is added and an insert is done it includes the pk field in the insert statement, however when that same record is later updated the pk field will not be included in the update statement.

Now if you edit a record and did not change the value of you pk field and PrimaryKeyUpdatable is set to TRUE then when you save the update statement includes the pk fld and it is updated with the same value so no harm really comes from it.

The SF guys added this property at my request I am using guid primekeys and merge replication. I have the prime key set as the rowguid for replication, if you try to update the pk field even with the same value it throws a sql exception which makes perfect sense.

I guess you can look at PrimaryKeyUpdatable = IncludePrimaryKeyFieldInUpdateStatement. It is probably not a bad idea to set it to false and turning it on only when you explicitly need to update a pk value.

I hope that helps am makes sense.

Paul

Edhy Rijo
E
StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)
Group: StrataFrame Users
Posts: 2.4K, Visits: 23K
Paul Chase (04/24/2008)

I hope that helps am makes sense.

Hi Paul,

Yes it does at least to me Smile  In my VFP application all my PK where GUID based since the creation of the GUID was very easy and light and it helped me when doing some remote synch with VFP tables.  I still have some projects which will be re-done in SF and the inclussion of this functionality will allow me to still use those GUID fields.  A couple of weeks ago, I did a small test of this functionality and it does work like a charm!

Edhy Rijo

Paul Chase
Paul Chase
Advanced StrataFrame User (580 reputation)Advanced StrataFrame User (580 reputation)Advanced StrataFrame User (580 reputation)Advanced StrataFrame User (580 reputation)Advanced StrataFrame User (580 reputation)Advanced StrataFrame User (580 reputation)Advanced StrataFrame User (580 reputation)Advanced StrataFrame User (580 reputation)Advanced StrataFrame User (580 reputation)
Group: Forum Members
Posts: 414, Visits: 2.8K
Hi edhy,

Guids as primekeys work fine with SF.

The issue I had was because I was using my guid primkeys as a merge replications rowguid column, This caused some issues that required the addition of the PrimaryKeyis Updatable property.

So If you are not using merge replication with guid primary keys and have set the merge replications rowguid field to the Prime key then the PrimaryKeyisupdateable setting wouldnt matter.

Here is some logic I have in my base class BO to assign the PK which may help you out if you haven't added it yet.

Protected Overrides Sub OnSetDefaultValues()

'DoDefault

MyBase.OnSetDefaultValues()

'-- Set Value for GUID PK

'-- Get a reference to the property descriptor (which doesn't use reflection)

Dim lodesc As FieldPropertyDescriptor = Me.GetPropertyDescriptor(Me.PrimaryKeyField)

'-- If the PK type is a Guid then Generate a Sequential GUID to prevent Index fragmentation

If lodesc.PropertyType Is GetType(Guid) Then

lodesc.SetValue(Me, Payroll.Base.Common.NewSequentialGUID)

End If


Trent Taylor
Trent Taylor
StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)
Group: StrataFrame Developers
Posts: 6.6K, Visits: 6.9K
Is there a table or primary key property in the DDT that sets the BO to PrimaryKeyIsAutoIncremented to true and PrimaryKeyIsUpdatable = false?

Paul answered the question as to why the field property exists in the DDT perfectly.  As for having a property that sets these properties, you really just need to create a base BO and inherit your BOs from the base BO with these properties set, this way you don't have to set them each time.

Imports MicroFour.StrataFrame.Business
Imports System.ComponentModel

Public Class MyBaseBO
    Inherits MicroFour.StrataFrame.Business.BusinessLayer

#Region " Private Fields "

    Private _PrimaryKeyIsAutoIncremented As Boolean = False
    Private _PrimaryKeyIsUpdatable As Boolean = True

#End Region

#Region " Public Properties "

    ''' <summary>
    ''' Gets or sets a value that determines whether the primary key for this business object is
    ''' auto-incremented within the data source (assigned by the database rather than by the
    ''' client).
    ''' </summary>
    <Category(EDITOR_CATEGORY_CRUD), _
    DefaultValue(False)> _
    Public Overrides Property PrimaryKeyIsAutoIncremented() As Boolean
        Get
            Return _PrimaryKeyIsAutoIncremented
        End Get
        Set(ByVal value As Boolean)
            _PrimaryKeyIsAutoIncremented = value
        End Set
    End Property


    ''' <summary>
    ''' Determines if the primary key field is updatable.  This property allows primary key fields that are not auto-incrementing to be used while
    ''' preventing an update error if the field is not updatable (i.e. Guid Primary Keys).
    ''' </summary>
    <Category(EDITOR_CATEGORY_CRUD), _
    DefaultValue(True)> _
    Public Overrides Property PrimaryKeyIsUpdatable() As Boolean
        Get
            Return _PrimaryKeyIsUpdatable
        End Get
        Set(ByVal value As Boolean)
            _PrimaryKeyIsUpdatable = value
        End Set
    End Property

#End Region

End Class

Note: You will need to be on 1.6.6 beta and load the attached business assembly into the GAC in order for this to work.  I had to add the Overridable tab to the PrimaryKeyIsAutoIncremented and PrimarykeyIsUpdatable properties.

Attachments
MicroFourStrataFrameBusiness.zip (106 views, 384.00 KB)
Edhy Rijo
E
StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)
Group: StrataFrame Users
Posts: 2.4K, Visits: 23K
Paul Chase (04/24/2008)
Here is some logic I have in my base class BO to assign the PK which may help you out if you haven't added it yet.

Hi Paul,

Thanks for the code must appreciated.  Of course I did not have it since I am currently not using GUID for the current project, but yes, I will use it. Hehe

Edhy Rijo

Trent Taylor
Trent Taylor
StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)
Group: StrataFrame Developers
Posts: 6.6K, Visits: 6.9K
One word of caution, if you are not planning on using replication you should not use GUID primary keys!  They create a lot of additional overhead and dramatically slow down queries on the SQL side versus an integer value.  So if you are planning on your databases getting very large, then I would highly recommend against using a GUID.  There is definintely a time and place for GUIDs and Paul's application is one of those, but if you are creating GUIDs just to create a GUIDs PK, then I would strongly recommnend against doing this.  We have been spending a lot of time in T-SQL lately and working on very complex queries and tracing execution paths...when you have a GUID as a primary key versus an integer, especially on a large database, the query can execute as much as 100 times slower (yes times, not percent).  A query that took 300 ms went to 3 ms.  So as the database becomes much larger and this same query took 1 second it would go from being 1 second to 10 ms.  This is a huge difference!

By taking this type of logic into account, we turned a query taking 4.5 seconds the other day on a very large database into 22 ms....that was a happy day BigGrin  We made an even larger impact when dealing with dates.  Instead of storing these fields that we will be testing on with >= or <= as a date, we stored them as ticks in a BigInt field.  This was the largest change in performance that we had seen thus far.  Databases deal with integer data better than strings when it comes to performance and parameters.  You won't have as large a hit on a PK field, but you don't want to box yourself into a corner either.

GO

Merge Selected

Merge into selected topic...



Merge into merge target...



Merge into a specific topic ID...




Similar Topics

Reading This Topic

Login

Explore
Messages
Mentions
Search