﻿<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>StrataFrame Forum » StrataFrame Application Framework - V1 » Business Objects and Data Access (How do I?)  » Updatable Primary Key problem</title><generator>InstantForum 2017-1 Final</generator><description>StrataFrame Forum</description><link>http://forum.strataframe.net/</link><webMaster>StrataFrame Forum</webMaster><lastBuildDate>Tue, 09 Jun 2026 01:39:18 GMT</lastBuildDate><ttl>20</ttl><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost18381.aspx</link><description>Today I started to implement GUID PK for a new SF project, and this thread showed to be an invaluable resource of information.&lt;P&gt;The code posted by Paul and Trent lead me to create my first Business Object base class and after creating 3 forms, you'll notice how useful is to&amp;nbsp;have of a base BO class to handle things for you :hehe:.&lt;/P&gt;&lt;P&gt;So I just want to say &lt;EM&gt;&lt;STRONG&gt;THANKS!&lt;/STRONG&gt;&lt;/EM&gt; to everybody who participated in this thread, (including me ;)) because it is worthy.</description><pubDate>Thu, 07 Aug 2008 21:06:34 GMT</pubDate><dc:creator>Edhy Rijo</dc:creator></item><item><title>Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15854.aspx</link><description>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.&lt;/P&gt;&lt;P&gt;For example, I have an Int32 primary key called "CustomerID" and&amp;nbsp;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).&lt;/P&gt;&lt;P&gt;I have tried setting PrimaryKeyIsUpdatable to true but I guess I haven't done it correctly as Save() never writes the primary key.&lt;/P&gt;&lt;P&gt;Can anyone help?&lt;/P&gt;&lt;P&gt;Thanks in advance.</description><pubDate>Thu, 07 Aug 2008 21:06:34 GMT</pubDate><dc:creator>Aaron Young</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15956.aspx</link><description>[quote]Too many times the replication has to be dropped, the upgrade applied and then replication turned back on again. This in itself is not necessarily the problem but we could be dealing with 50G+ databases which are then pushed out to the subscribers.[/quote]&lt;/P&gt;&lt;P&gt;The really nice thing that has been added in the 1.6.6 beta are pre and post deployment scripts.&amp;nbsp; This allows you to turn this off &lt;STRONG&gt;&lt;U&gt;&lt;EM&gt;if &lt;/EM&gt;&lt;/U&gt;&lt;/STRONG&gt;you need to....while still using the DDT.&amp;nbsp; This has become a very handy implementation that we have started using ourselves (pre and post deployment scripts that is :))</description><pubDate>Mon, 28 Apr 2008 11:38:13 GMT</pubDate><dc:creator>Trent L. Taylor</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15950.aspx</link><description>Hi Paul &amp;amp; Trent,&lt;/P&gt;&lt;P&gt;So the DDT can handle replicated databases? That is brilliant! :)&amp;nbsp;SQL Server 2005 does allows some minor upgrades to a replicated database but it is not enough and on some occasions it has even rolled back a new field addition 24 hours after it was applied. Too many times the replication has to be dropped, the upgrade applied and then replication turned back on again. This in itself is not necessarily the problem but we could be dealing with 50G+ databases which are then pushed out to the subscribers.&lt;/P&gt;&lt;P&gt;While it is true most PCs will have an NIC, we are faced with the situation when a single site PC with no interface has been creating transactions for years which then has to be merged with another of our systems. Basically, in our application, we really need a globally unique ID and I can't see beyond the ugly Guid(). In our case the sequential ID isn't guaranteed to be globally unique and wouldn't be any different to the integer mechanism we currently use - which still has conflicts from time to time.&lt;/P&gt;&lt;P&gt;Aaron</description><pubDate>Mon, 28 Apr 2008 10:52:17 GMT</pubDate><dc:creator>Aaron Young</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15947.aspx</link><description>Aaron, &lt;P&gt;If you have an application that is going to replicate it would need a Nic to be able to do so , but&amp;nbsp;I suppose it is possible that it could be an external type nic that is unplugged whilst the user is adding records. I went back and forth on the&amp;nbsp;what method to use&amp;nbsp;as well, below is some code that uses datetime ticks to sequence a guid.&lt;/P&gt;&lt;P&gt;As far as updating schema, with sql 2005 at least you can make some minor schema changes directly to the publisher. &lt;A href="http://msdn2.microsoft.com/en-us/library/ms151870.aspx"&gt;http://msdn2.microsoft.com/en-us/library/ms151870.aspx&lt;/A&gt;&amp;nbsp;.&lt;/P&gt;&lt;P&gt;However it is easy to get A.F.U when doing anything major. I have not had to change much except a few alter table's to add a column or 2, but in my next major release I will probably&amp;nbsp;be hating replication due to the number of schema changes&amp;nbsp;I will be making,&amp;nbsp;most likely&amp;nbsp;I'll end up&amp;nbsp;having to drop and re-add subsciptions. &lt;/P&gt;&lt;P&gt;In my case however&amp;nbsp;I can restrict&amp;nbsp;my users from using the software until the database and application&amp;nbsp;has been updated. I create software for internal use only so I have more flexibilty than some when it comes to things like that.&lt;/P&gt;&lt;P&gt;[codesnippet]&lt;FONT size=2&gt;&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;''' &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&amp;lt;summary&amp;gt;&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;''' Creates A Seqeuntial Guid based on Date time values&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;''' &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&amp;lt;/summary&amp;gt;&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;''' &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&amp;lt;returns&amp;gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;Sequential Guid&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&amp;lt;/returns&amp;gt;&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;''' &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&amp;lt;remarks&amp;gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;converted from c# code found at &lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;''' http://www.informit.com/discussion/index.aspx?postid=a8275a70-0698-46f0-8c8f-bf687464628c&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;''' I changed it slightly to use utc time due to Pensacola and Ft Walton being Central Time&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;''' so there would not be a time zone problem &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&amp;lt;/remarks&amp;gt;&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Shared&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Function&lt;/FONT&gt;&lt;FONT size=2&gt; NewSequentialGuid() &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;As&lt;/FONT&gt;&lt;FONT size=2&gt; Guid&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Dim&lt;/FONT&gt;&lt;FONT size=2&gt; laGuid() &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;As&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Byte&lt;/FONT&gt;&lt;FONT size=2&gt; = Guid.NewGuid.ToByteArray&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Dim&lt;/FONT&gt;&lt;FONT size=2&gt; ldBaseDate &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;As&lt;/FONT&gt;&lt;FONT size=2&gt; DateTime = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;New&lt;/FONT&gt;&lt;FONT size=2&gt; DateTime(1899, 1, 1)&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Dim&lt;/FONT&gt;&lt;FONT size=2&gt; ldNow &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;As&lt;/FONT&gt;&lt;FONT size=2&gt; DateTime = DateTime.UtcNow&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;' Get the days and milliseconds which will be used to build the byte string &lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Dim&lt;/FONT&gt;&lt;FONT size=2&gt; lsdays &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;As&lt;/FONT&gt;&lt;FONT size=2&gt; TimeSpan = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;New&lt;/FONT&gt;&lt;FONT size=2&gt; TimeSpan((ldNow.Ticks - ldBaseDate.Ticks))&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Dim&lt;/FONT&gt;&lt;FONT size=2&gt; lsmsecs &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;As&lt;/FONT&gt;&lt;FONT size=2&gt; TimeSpan = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;New&lt;/FONT&gt;&lt;FONT size=2&gt; TimeSpan((ldNow.Ticks _&lt;/P&gt;&lt;P&gt;- (&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;New&lt;/FONT&gt;&lt;FONT size=2&gt; DateTime(ldNow.Year, ldNow.Month, ldNow.Day).Ticks)))&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;' Convert to a byte array &lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Dim&lt;/FONT&gt;&lt;FONT size=2&gt; laDays() &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;As&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Byte&lt;/FONT&gt;&lt;FONT size=2&gt; = BitConverter.GetBytes(lsdays.Days)&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;'SQL Server is accurate to 0.003 part of a second&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;'.NET DateTime ticks are in milliseconds&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;'so we divide .NET ticks by 3.333333 and should be ok &lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Dim&lt;/FONT&gt;&lt;FONT size=2&gt; laSecs() &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;As&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Byte&lt;/FONT&gt;&lt;FONT size=2&gt; = BitConverter.GetBytes(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;CType&lt;/FONT&gt;&lt;FONT size=2&gt;((lsmsecs.TotalMilliseconds / 3.333333), &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Long&lt;/FONT&gt;&lt;FONT size=2&gt;))&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;'Reverse the bytes to match SQL Servers ordering &lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;Array.Reverse(laDays)&lt;/P&gt;&lt;P&gt;Array.Reverse(laSecs)&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;' Copy the bytes into the guid &lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;Array.Copy(laDays, (laDays.Length - 2), laGuid, (laGuid.Length - 6), 2)&lt;/P&gt;&lt;P&gt;Array.Copy(laSecs, (laSecs.Length - 4), laGuid, (laGuid.Length - 4), 4)&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;'Send it back&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Return&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;New&lt;/FONT&gt;&lt;FONT size=2&gt; System.Guid(laGuid)&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;End&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Function&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;[/codesnippet]</description><pubDate>Mon, 28 Apr 2008 10:10:15 GMT</pubDate><dc:creator>Paul Chase</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15926.aspx</link><description>[quote]While we are on the subject, does the Database Deployment Toolkit support upgrading of replicated databases?[/quote]&lt;/P&gt;&lt;P&gt;I have been sick over the weekend and my wife is trying to keep me in bed so I don't get worse...but she had to go to the store :D so I thought I would do a little catching up on the forum.&lt;/P&gt;&lt;P&gt;To answer your question, yes, the DDT will most definitely update a database structure for a SQL Server that uses replication.&amp;nbsp; When doing this, however, it is best to update the structures when there will be the least amount of activity on the databases (none if possible).&amp;nbsp; but in any case, you can actually write a program to deploy your structures using the DatbaseMigrator class.&amp;nbsp; There is a sample that comes with the framework that shows how to do this.&amp;nbsp; You can create a program that updates all servers on separate threads at the same time...reducing deployment time and making the process more streamlined.&amp;nbsp; It is the same thing that you would do otherwise, just updating multiple servers on different threads at the same time.&lt;/P&gt;&lt;P&gt;On a separate note here, there has been a lot of discussion on GUIDs and sequential GUIDs.&amp;nbsp; There is one problem wth sequential GUIDs that exists when you will not&amp;nbsp;be talking to a server and you need to come back in and merge the data.&amp;nbsp; It is the same problem that exists when using integers.&amp;nbsp; If you come up with a mechanism to create sequential GUIDs, and you take a laptop, let's say, offsite and it creates records, and there are other laptops doing the same thing, then you can definitly have sync issues.&amp;nbsp; So this then turns into the situation where each laptop has its own pre-set range to work within, with ends up having the same issues as using a PK.&lt;/P&gt;&lt;P&gt;I recommend doing a little test.&amp;nbsp; I am of the mind that it is easier to deal with the one outlier that may (though it is extremely unlikely) produce a duplicate GUID.&amp;nbsp; If you create a program that creates new records non-stop using the System.Guid.NewGuid() for 24-48 hours (this will prouce some SERIOUS records!)&amp;nbsp; I believe that you will find that there will more than likely never be a duplicate.&amp;nbsp; If you del with disconnected data (pre-merge or replication) in thi maanner and perform a "pre-merge" query to ensure that there are no duplicates, then you don't get into the syncing issue of sequential GUIDs.&amp;nbsp; This is just some food for thought.</description><pubDate>Sun, 27 Apr 2008 14:45:31 GMT</pubDate><dc:creator>Trent L. Taylor</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15918.aspx</link><description>[quote][b]Aaron Young (04/26/2008)[/b][hr]While I like the idea of sequential GUIDs the problem with UuidCreateSequential is it still uses the mac address and it may only guarantee uniqueness on the local PC if the PC doesn't have a network adapter.[/quote]&lt;P&gt;Hummm, &amp;nbsp;not NIC, not program to run :P</description><pubDate>Sat, 26 Apr 2008 15:57:30 GMT</pubDate><dc:creator>Edhy Rijo</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15917.aspx</link><description>I may be wrong but I believe Microsoft switched to version 4 GUIDs from Windows 2000 onwards. This version doesn't use the mac address as it was deemed a security risk given that it allowed the GUID to be traced back to a PC. Version 4 GUIDs uses random parts for all sections.&lt;/P&gt;&lt;P&gt;While I like the idea of sequential GUIDs the problem with UuidCreateSequential is it still uses the mac address and it may only guarantee uniqueness on the local PC if the PC doesn't have a network adapter.</description><pubDate>Sat, 26 Apr 2008 15:38:37 GMT</pubDate><dc:creator>Aaron Young</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15910.aspx</link><description>Hi Aaron,&lt;/P&gt;&lt;P&gt;As I understand it is the presence of&amp;nbsp;the network card's mac address (on the machine creating the GUID) in the GUID algorithm assures uniqueness.&lt;/P&gt;&lt;P&gt;Peter</description><pubDate>Fri, 25 Apr 2008 21:13:33 GMT</pubDate><dc:creator>Peter Jones</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15908.aspx</link><description>One consequence of using any form of replication is future changes to the database schema. Most database schema comparison/updating tools have problems upgrading a database currently in use for replication. In an ideal world you would be able to change your database schema which would then be replicated across to other databases. SQL Server 2005 is better at allowing some updating but most upgrading tools will fail on a replicated database which could force you to remove replication, upgrade and then setup replication again.&lt;/P&gt;&lt;P&gt;While we are on the subject, does the Database Deployment Toolkit support upgrading of replicated databases?&lt;/P&gt;&lt;P&gt;I like the idea of sequential GUIDs but does this still guarantee they will be globally unique?</description><pubDate>Fri, 25 Apr 2008 17:25:25 GMT</pubDate><dc:creator>Aaron Young</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15903.aspx</link><description>Like Trent said there are&amp;nbsp;a ton&amp;nbsp;of articles explaining the different types of replication written by people that know it and can explain it&amp;nbsp;way better than I could.&lt;/P&gt;&lt;P&gt;Just like the decision to use integer or guid primary keys it really depends' on your business requirements as to what replication scenario would work best for you. Also do not forget that StrataFrame has the Enterprise Server which may be a better option again depending on what your requirements are.&lt;/P&gt;&lt;P&gt;Paul</description><pubDate>Fri, 25 Apr 2008 14:07:25 GMT</pubDate><dc:creator>Paul Chase</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15896.aspx</link><description>Great!&lt;/P&gt;&lt;P&gt;Thanks Trent.</description><pubDate>Fri, 25 Apr 2008 13:29:23 GMT</pubDate><dc:creator>Edhy Rijo</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15892.aspx</link><description>Edhy,&lt;P&gt;Here is a step-by-step on setting up Merge Replication.&amp;nbsp; Just serach on Google for about 1000 more articles.&lt;/P&gt;&lt;P&gt;&lt;A href="http://www.databasejournal.com/features/mssql/article.php/1438231"&gt;http://www.databasejournal.com/features/mssql/article.php/1438231&lt;/A&gt;&amp;nbsp;&lt;P&gt;And Paul is right on the sequential GUIDs...that is definitely the safest route to go.</description><pubDate>Fri, 25 Apr 2008 13:02:37 GMT</pubDate><dc:creator>Trent L. Taylor</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15891.aspx</link><description>[quote][b]Paul Chase (04/25/2008)[/b][hr]I now use Sql&amp;nbsp;merge replication and guids to great effect. &lt;EM&gt;One thing that is a business requirment for me is the abilitly for an office to function without an UP network connection to corporate thus a client server type of environment would not work&lt;/EM&gt;.[/quote]&lt;/P&gt;&lt;P&gt;Wow Paul, thanks for sharing this info with us.&lt;/P&gt;&lt;P&gt;My next VFP conversion project will definately make use of this code since the use of a GUID PK is a must.&lt;/P&gt;&lt;P&gt;About the above comment, would you mind explaining a bit more about how to use SQL merge replication I also have those needs for my next conversion project.</description><pubDate>Fri, 25 Apr 2008 11:57:35 GMT</pubDate><dc:creator>Edhy Rijo</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15890.aspx</link><description>&amp;nbsp;Guys,&lt;P&gt;If you&amp;nbsp;want to use GUID's then you &lt;STRONG&gt;definately&lt;/STRONG&gt; will want to create the guid sequentially. using the Guid.NewGuid function will create a truly random unsequential&amp;nbsp;guid which well cause performance to suffer.&amp;nbsp;By creating a sequential guid you are ensuring that&amp;nbsp;records are inserted at the end thus keeping page splits and index fragmentation to a minimum.This is primarily what causes perfomance problem's when people use guid's as primary keys.Using this approach you will approach insert and select perfomance that is&amp;nbsp;much closer to using ints. You still will have the&amp;nbsp;usual drawbacks&amp;nbsp;of using guids they are ugly and big etc.&amp;nbsp;There are several articles that detail this in more depth just google sequential guids.&lt;/P&gt;&lt;P&gt;I have 17 offices that&amp;nbsp;I converted\converting from Foxpro 2.6. I had a very elaborate data merge process for&amp;nbsp;consolidating data at&amp;nbsp;corporate office that ran all night for several hours. I now use Sql&amp;nbsp;merge replication and guids to great effect. One thing that is a business requirment for me is the abilitly for an office to function without an UP network connection to corporate thus a client server type of environment would not work.&lt;/P&gt;&lt;P&gt;I have not had any perfomance issues so far, Like anything else it always comes down to making a decision based on your unique business requirements. &lt;/P&gt;&lt;P&gt;Below is a code snippet to generate a SEQUENTIAL Guid and to add it in the default values of you base BO.&lt;/P&gt;&lt;P&gt;[codesnippet]&lt;/P&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Protected&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Overrides&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Sub&lt;/FONT&gt;&lt;FONT size=2&gt; OnSetDefaultValues()&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;'DoDefault&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;MyBase&lt;/FONT&gt;&lt;FONT size=2&gt;.OnSetDefaultValues()&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;'-- Set Value for GUID PK &lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;'-- Get a reference to the property descriptor (which doesn't use reflection)&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Dim&lt;/FONT&gt;&lt;FONT size=2&gt; lodesc &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;As&lt;/FONT&gt;&lt;FONT size=2&gt; FieldPropertyDescriptor = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Me&lt;/FONT&gt;&lt;FONT size=2&gt;.GetPropertyDescriptor(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Me&lt;/FONT&gt;&lt;FONT size=2&gt;.PrimaryKeyField)&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;'-- If the PK is a Guid Generate a Sequential GUID to prevent Index fragmentation&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;If&lt;/FONT&gt;&lt;FONT size=2&gt; lodesc.PropertyType &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Is&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;GetType&lt;/FONT&gt;&lt;FONT size=2&gt;(Guid) &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Then&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;lodesc.SetValue(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Me&lt;/FONT&gt;&lt;FONT size=2&gt;, Payroll.Base.Common.NewSequentialID)&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;End&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;If&lt;/P&gt;&lt;/FONT&gt;&lt;P&gt;End Sub&lt;/P&gt;&lt;P&gt;in my common class&lt;/P&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Declare&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Function&lt;/FONT&gt;&lt;FONT size=2&gt; UuidCreateSequential &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Lib&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;"Rpcrt4.dll"&lt;/FONT&gt;&lt;FONT size=2&gt; (&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;ByRef&lt;/FONT&gt;&lt;FONT size=2&gt; guid &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;As&lt;/FONT&gt;&lt;FONT size=2&gt; Guid) &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;As&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Integer&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;''' &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&amp;lt;summary&amp;gt;&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;''' Creates A Seqentail GUID&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;''' &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&amp;lt;/summary&amp;gt;&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;''' &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;''' &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&amp;lt;remarks&amp;gt;&amp;lt;/remarks&amp;gt;&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Shared&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Function&lt;/FONT&gt;&lt;FONT size=2&gt; NewSequentialID() &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;As&lt;/FONT&gt;&lt;FONT size=2&gt; Guid&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;'-- Local Variables&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Dim&lt;/FONT&gt;&lt;FONT size=2&gt; Retval &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;As&lt;/FONT&gt;&lt;FONT size=2&gt; Guid&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Dim&lt;/FONT&gt;&lt;FONT size=2&gt; LnResult &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;As&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Integer&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Try&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;LnResult = UuidCreateSequential(Retval)&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;If&lt;/FONT&gt;&lt;FONT size=2&gt; LnResult = 0 &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Then&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Return&lt;/FONT&gt;&lt;FONT size=2&gt; Retval&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Else&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Throw&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;New&lt;/FONT&gt;&lt;FONT size=2&gt; Exception(&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;"UuidCreateSequential failed: "&lt;/FONT&gt;&lt;FONT size=2&gt; &amp;amp; LnResult)&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;End&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;If&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Catch&lt;/FONT&gt;&lt;FONT size=2&gt; ex &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;As&lt;/FONT&gt;&lt;FONT size=2&gt; Exception&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Throw&lt;/FONT&gt;&lt;FONT size=2&gt; (ex)&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;End&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Try&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;End&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Function&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;[/codesnippet]</description><pubDate>Fri, 25 Apr 2008 11:31:01 GMT</pubDate><dc:creator>Paul Chase</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15877.aspx</link><description>Hi Edhy,&lt;/P&gt;&lt;P&gt;That is good to know. We have tested with GUIDs to a limited degree and it looked okay but our big problem will be converting legacy databases to a new format. Some of the databases are literally in use 24x7x365. But I guess that problem is for another day.</description><pubDate>Thu, 24 Apr 2008 16:36:54 GMT</pubDate><dc:creator>Aaron Young</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15876.aspx</link><description>Hi Aaron,&lt;/P&gt;&lt;P&gt;I have a VFP application installed in 17 branches which synchronize to the main office.&amp;nbsp; My solution was to used GUID PK and a BranchID field, the GUID works just find and in the main office where all the repository is there has not been performance issues because all the fields are properly indexed and the generation of reports is normal.&amp;nbsp; &lt;/P&gt;&lt;P&gt;I should note that the synch process is one way only from branches to the main office and that may not be your case.&amp;nbsp; So if I would have to do this project in SF I would need to re-think the logic since instead of synchronizing I would have all branches connected to the main office database using SF Enterprise server, but still using the GUID PK.</description><pubDate>Thu, 24 Apr 2008 15:57:25 GMT</pubDate><dc:creator>Edhy Rijo</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15875.aspx</link><description>I think you are right Trent. Whatever way we have tried to&amp;nbsp;engineer it, it still results in conflicts somewhere down the line. Of course, that leaves us with a real headache as we have a large no of customer databases that need to be converted from the old legacy database running with int PKs to a revised database with GUIDs PK.</description><pubDate>Thu, 24 Apr 2008 15:56:51 GMT</pubDate><dc:creator>Aaron Young</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15874.aspx</link><description>In your case I would probably go with GUIDs so that you do not have to engineer the global PKs.&amp;nbsp; When weighing the costs between the two the ease of the GUIDs would win out in my eyes as we have tried to engineer the other behavior in more than one instance and it always ends up out of sync at some point which causes issues.&amp;nbsp; This would fall under the replication category that Paul was talking about earlier.</description><pubDate>Thu, 24 Apr 2008 15:52:11 GMT</pubDate><dc:creator>Trent L. Taylor</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15872.aspx</link><description>Very interesting performance information about GUIDs which is a concern as we were looking to migrate to GUIDs from int PKs.&lt;/P&gt;&lt;P&gt;We have a legacy system that involves many distributed databases per customer. All databases must be updatable even if the WAN connection is down. As a result, our int PKs must be globally unique which is why we have to update the PKs from the application. We had planned on migrating to a new database model that used GUIDs but these performance figures are worrying.&lt;/P&gt;&lt;P&gt;Unfortunately, our PKs must be globally unique across all databases and other than the performance problem, GUIDs looked the easiest option for an automatic solution rather than our manual int solution.</description><pubDate>Thu, 24 Apr 2008 15:18:08 GMT</pubDate><dc:creator>Aaron Young</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15871.aspx</link><description>[quote]Does the newsequentialid() function in SQL 2005 change any of the thinking about considering use of UIDs?&amp;nbsp; would it be difficult to have newsequentialid() used to create UIDs on the back end?&amp;nbsp;[/quote]&lt;/P&gt;&lt;P&gt;This isn't the issue.&amp;nbsp; The issue is not when creating the PK, but rather when performing queries on the data.&amp;nbsp; In VFP we used to use Integer PKs which was extremely frustrating because they did not have the AutoInc stuff when we started (and their AutoInc is nowhere in the same universe as SQL Server).&amp;nbsp; However, since we used Integer PKs life did get much better once we got on SQL Server and did not have to convert from GUIDs to Integer PKs.&lt;/P&gt;&lt;P&gt;But back to the original point, the issue is not when creating the PK.&amp;nbsp; If you want to use a GUID PK, don't let the server assign it, just call the System.Guid.NewGuid() method in the SetDefaultValues of the business object versus relying on the server.&amp;nbsp; It is basically impossible to get two GUIDs of the same uniqueness anyway.&lt;/P&gt;&lt;P&gt;When using identiy fields in SQL Server, the BO has the ability to automatically retrieve the PK once a new record is created, which I am sure that you have already discovered.&amp;nbsp; So the issue isn't the whole NextId() thing that you faced in VFP, but rather when you start to query the data to retrieve records within the DB.&lt;/P&gt;&lt;P&gt;Hope that makes sense :)</description><pubDate>Thu, 24 Apr 2008 14:20:09 GMT</pubDate><dc:creator>Trent L. Taylor</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15869.aspx</link><description>I certainly defer to you experience regarding using guids with newid()&amp;nbsp; in SF.&amp;nbsp; In vfp/vfe I would use guids because generating the key on the front end saved a trip to the server before populating child fks and I often had situations where tables were going to be merged or data moved around among numerous installations of a program.&amp;nbsp; But I do see the problems - and the problems regarding using UID with a clustered index are obvious.&amp;nbsp; &lt;P&gt;I am very impressed with the way SF seems to give the best of both worlds in one sense - handling the fk thing with integer keys with no problem.&amp;nbsp; &lt;/P&gt;&lt;P&gt;Does the newsequentialid() function in SQL 2005 change any of the thinking about considering use of UIDs?&amp;nbsp; would it be difficult to have newsequentialid() used to create UIDs on the back end?&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'm pretty sure I'll be using Int keys in SF for the most part, but just wondered about the practicality of sequential UIDs ?&lt;/P&gt;&lt;P&gt;&lt;A href="http://www.fotia.co.uk/fotia/DY.19.NewSequentialId.aspx"&gt;http://www.fotia.co.uk/fotia/DY.19.NewSequentialId.aspx&lt;/A&gt;</description><pubDate>Thu, 24 Apr 2008 12:42:58 GMT</pubDate><dc:creator>Charles R Hankey</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15866.aspx</link><description>Thanks Trent, points taken.:hehe:</description><pubDate>Thu, 24 Apr 2008 11:33:10 GMT</pubDate><dc:creator>Edhy Rijo</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15863.aspx</link><description>One word of caution, if you are not planning on using replication you should not use GUID primary keys!&amp;nbsp; They create a lot of additional overhead and dramatically slow down queries on the SQL side versus an integer value.&amp;nbsp; So if you are planning on your databases getting very large, then I would highly recommend against using a GUID.&amp;nbsp; 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.&amp;nbsp; 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).&amp;nbsp; A query that took 300 ms went to 3 ms.&amp;nbsp; So as the database becomes much larger and this same query took 1 second it would go from being 1 second to 10 ms.&amp;nbsp; This is a huge difference!&lt;P&gt;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 :D&amp;nbsp; We made an even larger impact when dealing with dates.&amp;nbsp; Instead of storing these fields that we will be testing on with &amp;gt;= or &amp;lt;= as a date, we stored them as ticks in a BigInt field.&amp;nbsp; This was the largest change in performance that we had seen thus far.&amp;nbsp; Databases deal with integer data better than strings when it comes to performance and parameters.&amp;nbsp; You won't have as large a hit on a PK field, but you don't want to box yourself into a corner either.</description><pubDate>Thu, 24 Apr 2008 10:30:48 GMT</pubDate><dc:creator>Trent L. Taylor</dc:creator></item><item><title>RE: Updatable Primary Key problem</title><link>http://forum.strataframe.net/FindPost15862.aspx</link><description>[quote][b]Paul Chase (04/24/2008)[/b][hr]Here is&amp;nbsp;some logic&amp;nbsp;I have&amp;nbsp;in my base class BO to assign the PK which may help you out if you haven't added it yet.[/quote]&lt;P&gt;Hi Paul,&lt;/P&gt;&lt;P&gt;Thanks for the code must appreciated.&amp;nbsp; 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:</description><pubDate>Thu, 24 Apr 2008 10:25:06 GMT</pubDate><dc:creator>Edhy Rijo</dc:creator></item></channel></rss>