Sql Replication Guid Field


Author
Message
Paul Chase
Paul Chase
Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)
Group: Forum Members
Posts: 414, Visits: 2.8K
I am planning on using replication between branch offices and the corporate office. Using replication requires a guid field in each table which is fine, I am even considering using it as my primary keys as each office's data will be consolidated into one db.

The real problem I am having is the column with the Guid type is set to have a default value of newsequentialid() which from what I have read eliminates alot of the index issues with using guids by making the id sequential. How do I configure the BO to pass default to allow sql to generate newid. I know I can generate a guid on the .net side but it does not seem to be sequential.

Thanks

P

StrataFrame Team
S
StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)
Group: StrataFrame Developers
Posts: 3K, Visits: 2.5K
What you'll need to do is leave the business object's PrimaryKeyIsAutoIncremented property to True. This will inform the business object that the server needs to assign the GUID value. Then, just like you said, put the NewSequentialID() function as the default value for a column. When your business object saves the record, it will insert a NULL value for the PK and retrieve the assigned value from the server, just as if it was an IDENTITY column.
Paul Chase
Paul Chase
Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)
Group: Forum Members
Posts: 414, Visits: 2.8K
Ben currently I am not using it as a Pk field. Sql added the Field when I set up replication. I am considering using it as a Pk however. Is there a way to do this without it being a PK? 
StrataFrame Team
S
StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)
Group: StrataFrame Developers
Posts: 3K, Visits: 2.5K
No, not really. For the business object to automatically retrieve the value without you needing to requery after saving the new records, it will need to be the PK.
Paul Chase
Paul Chase
Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)
Group: Forum Members
Posts: 414, Visits: 2.8K
Ok,

I guess that makes my decision on using them for PK's. Smile

Paul Chase
Paul Chase
Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)
Group: Forum Members
Posts: 414, Visits: 2.8K
Ben Chase (05/04/2006)
What you'll need to do is leave the business object's PrimaryKeyIsAutoIncremented property to True. This will inform the business object that the server needs to assign the GUID value. Then, just like you said, put the NewSequentialID() function as the default value for a column. When your business object saves the record, it will insert a NULL value for the PK and retrieve the assigned value from the server, just as if it was an IDENTITY column.

Ben this doesn't work i receive the following error.

Cannot create INSERT command because PrimaryKeyIsAutoIncremented = True and the PrimaryKeyField is not a valid auto-increment data type.

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

Here is a shot from Sql

StrataFrame Team
S
StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)
Group: StrataFrame Developers
Posts: 3K, Visits: 2.5K
Well, Paul, you're right, and there is no way to retrieve the last created GUID through either the NewID or NewSequencialID methods. We have a pending feature request for the ability to retrieve columns other than the PK from the server. Essentially, you specify the column(s) you want to retrieve from the server after an insert and the BO retrieves them... Looks like you'll have to wait until that feature is implemented to do what you want to do. Then, you can make your Primary Key an IDENTITY integer, and let replication services have it's GUID column that's assigned either by NewID or NewSequencialID and gets retrieved after you insert a new record.



I'll try to get that feature request bumped up and let you know when it's implemented Ermm
Paul Chase
Paul Chase
Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)Advanced StrataFrame User (806 reputation)
Group: Forum Members
Posts: 414, Visits: 2.8K
Thanks Ben,

I was kinda hopeful to use guid's as a primary key the more I thought about it. My current PK in an int type that is prefixed by a 3 digit office code. While this approach works it is not nessasarily ideal for a number of reasons.

However googling around I found some examples to "modifiy" a guid to make it sequential by datetime. I have a guid field as my primary key no default value set and rowguid set to no, auto increment turned off on the BO. I am setting the pk_id in the setdefaultvalues method of the bo. I get the following error. 

Private Sub SalesmenBO_SetDefaultValues()

Me.sm_pk_id = NewSeqGuid()

End Sub

Cannot insert explicit value for identity column in table 'salesmen' when IDENTITY_INSERT is set to OFF. 

What is the correct way to provide my own pk?

 

Public Shared Function NewSeqGuid() As Guid

Dim laGuid() As Byte = System.Guid.NewGuid.ToByteArray

Dim ldBaseDate As DateTime = New DateTime(1900, 1, 1)

Dim ldNow As DateTime = DateTime.Now

' Get the days and milliseconds which will be used to build the byte string

Dim strucdays As TimeSpan = New TimeSpan((ldNow.Ticks - ldBaseDate.Ticks))

Dim strucmsecs As TimeSpan = New TimeSpan((ldNow.Ticks _

- (New DateTime(ldNow.Year, ldNow.Month, ldNow.Day).Ticks)))

' Convert to a byte array

' Note that SQL Server is accurate to 1/300th of a millisecond so we divide by 3.333333

Dim laDays() As Byte = BitConverter.GetBytes(strucdays.Days)

Dim laSecs() As Byte = BitConverter.GetBytes(CType((strucmsecs.TotalMilliseconds / 3.333333), Long))

' Reverse the bytes to match SQL Servers ordering

Array.Reverse(laDays)

Array.Reverse(laSecs)

' Copy the bytes into the guid

Array.Copy(laDays, (laDays.Length - 2), laGuid, (laGuid.Length - 6), 2)

Array.Copy(laSecs, (laSecs.Length - 4), laGuid, (laGuid.Length - 4), 4)

Return New System.Guid(laGuid)

End Function


StrataFrame Team
S
StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)
Group: StrataFrame Developers
Posts: 3K, Visits: 2.5K
What you have is correct. The problem is that one of the columns in your table has an IDENTITY specification on it. Check the columns on your table and make sure that you don't have IDENTITY turned on on any of them.



But yes, you are correct in that when you want to use a GUID pk, you're better off creating your own guids on the client side than trying to retrieve the value from the server.
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