CodeSmith Community
Your Code. Your Way. Faster!

Blank guid! URGENT

Latest post 12-11-2007 9:34 AM by Andrewiski. 40 replies.
  • 08-28-2007 9:42 AM In reply to

    • PhilD
    • Top 500 Contributor
    • Joined on 08-13-2007
    • Posts 17
    • Points 475

    Re: Another question about defaulting to guid.empty

    My primary reason is that using the OUTPUT clause kills a whole bunch of birds with one stone. Getting the actual values back from the row solves a bunch of questions and issues i've seen around here related to default values.

    There doesn't seem to be any support for the OUTPUT clause at the moment. I'm looking at the insert proc and it does a SELECT to retrieve all computed columns, but it assumes it knows what the primary key is (or gets it from SCOPE_IDENTITY). For NewSequentialId, that won't work. OUTPUT is 2005-specific too.

     Of note is that you don't have to create a table variable unless there is a trigger on the table, if you just output the fields they will be returned just as a standard select statement would.
     

    I didn't know that, thanks. However, it would be dangerous to assume that there is no trigger on the table, one would have to pick a solution that works irrespective of whether there is a trigger or not. In our company we often use triggers for auditing, for example. I was thinking about your comments last night and there's no reason why we can't both get what we want - use Combs for UNIQUEIDENTIFIER columns with no default or a default of NewId(), and use your suggestion for columns with a default of NewSequentialId().

     

    Filed under: ,
    • Post Points: 35
  • 08-28-2007 9:52 AM In reply to

    • evolved
    • Top 50 Contributor
    • Joined on 12-27-2004
    • South River, NJ
    • Posts 96
    • Points 1,840

    Re: Another question about defaulting to guid.empty

     Hey phil, either you are trolling me or are being passive aggresive about this. If you carefully read this entire thread you'll notice I recommended using this as a SQL 2005 specific feature (of which .netTeirs already has a few). Also, where you do see it doesn't work with NewSequentialId, because I can clearly google and get oh about 5 results about SQL MVP's lauding the output clause for this specific use. About seeing if a trigger is on the table - dude we have the whole db schema at generation time! Of course we would know and take the appropriate action. As far as forcing people to use COMB: I dont think my boss would understand why we have touse COMB's he thinks that SQL server's use of NEWID() is just fine for him and I'd have to sell him on a different GUID generator that sole purpose is defeated by the fact that NewSequentialID exists. He would always prefer we chose the MS implimentation.

     

    http://www.jheidt.com
    ------------------------------
    Member of the .NetTiers team
    http://www.nettiers.com
    ------------------------------

    • Post Points: 35
  • 08-28-2007 10:29 AM In reply to

    • PhilD
    • Top 500 Contributor
    • Joined on 08-13-2007
    • Posts 17
    • Points 475

    Re: Another question about defaulting to guid.empty

    Hey phil, either you are trolling me or are being passive aggresive about this.

    I don't care for that accusation, thank you. It is completely unwarranted.

    Also, where you do see it doesn't work with NewSequentialId,

    If you read my post carefully you will see that I said the current SELECT technique doesn't work with NewSequentialId(), my intent was to point out that OUTPUT would be needed - oh yeah, that means somebody would have to write the template.

    About seeing if a trigger is on the table - dude we have the whole db schema at generation time! Of course we would know and take the appropriate action.

    For a table with a NewSequentialId() constraint and a trigger, what appropriate action do you suggest? You're telling me OUTPUT won't work with a table that has a trigger on it, I don't know I haven't tested it, but it would seem that if you are correct then in this case you are "stuck" with no way of getting back the GUID.

    A little less hostility and a little more contribution would be welcome, as I pointed out up thread it is possible for us both to get what we want. I've made a patch that does what I want - why don't you get HEAD from svn, apply my patch, then add your changes on top of it?

     

     

    • Post Points: 35
  • 08-28-2007 1:47 PM In reply to

    • swin
    • Top 10 Contributor
    • Joined on 06-14-2006
    • London, UK
    • Posts 925
    • Points 34,785

    Re: Another question about defaulting to guid.empty

    ..sheesh! I go away for a couple of days and trouble breaks out!Stick out tongue

    It's clear that you both want slighty different things and where this has happened previously we put in a new gen property that allows you to select what you want - so essentially I'm saying that Phil's last comment seems a good starting point.

    evolved - would you be able to add your requirement(code) in as an gen option i.e. NewGuidStyle - and provide options as appropriate?

    hth

    swin

    ------------------------------------------------- Member of the .NetTiers team -------------------------------------------------
    • Post Points: 35
  • 08-28-2007 9:30 PM In reply to

    Suggested Solution

    Apologies in advance for the long post... 

    I've just had a look at the COMB approach and although the creator did a good job figuring it out (http://www.informit.com/articles/article.aspx?p=25862&seqNum=1) he did so to cover the gap as it existed in SQL 2000. The author does later acknowledge the introduction of NewSequentialId() (http://www.jnsk.se/weblog/posts/combkiller.htm), but doesn't actually assess whether it's really any better than COMB (even though his blog title of "COMB Killer" implies he did). Two points of note from the original article is that the author states that if multiple records are created within 1/300th second that his approach would result in non-sequential GUIDs as his are only sequential to the granularity of a 6 byte datetime value (though probably not a point of concern for most databases) and that collisions are more likely within that timeframe due to there being less "random" bytes as 6 would be fixed for that 1/300th second block (but this weakness might prove a strength in the long run as collisions from 1/300th second block would impossible with another 1/300th second block for upwards of 77 years I think he mentioned).

    I think if I were creating a disconnected application (e.g. local windows clients feeding back into a central DB via web services for example) COMB would probably work better as it's based on what time it was generated, not what machine it's on. This benefit to indexing when the data is consolidated would probably be enough to warrant integrating an external GUID generator, but not for single DB server implementations in my opinion. Another scenario to consider though are scenarios such as a DB hosted on a passive/active cluster where the active node occasionally switches as this would create a new "series" of GUIDs and could muck with indexing to varying degrees (I'm thinking of a scenario where the new MAC address results in GUIDs which are "lower" than the existing ones meaning any new inserts are slotted in the middle of the index). Any form of replication would generally result in this I'd think (e.g. log shipping to a disaster recovery site, true replication, etc). That said, I'm with Swin in that I think you should always use whats native to the environment unless you have a decent reason not to (e.g. performance, scalability, missing feature, etc).

    As a result I believe NetTiers should be enhanced to support both COMB and NewSequentialId(). How that's achieved is the real question. If a DBA or software architect defines a default on a DB column then it should be used and not overridden by a code generator framework (as is the current situation with NewId() for example, but I think we're stuck with that one for reasons above). I'm not adverse to Phil's suggestion of using COMB when there is no default on the column, but only if the column does not allow nulls (as there are situations you may want to assign a GUID conditionally). So, if a GUID does not allow nulls, has no default and no value has been provided to the data access layer then creating a GUID in the data access layer would seem acceptable to me. I would prefer it be a configuration setting though as to what implementation gets used and for the moment the default would be "Guid.NewGuid()" with an alternate choice of "COMB". It wouldn't surprise me if another approach is created by somebody in the near future as COMB isn't perfect and could be improved again (maybe the same guy will create COMB 2.0). Does that sound ok to everyone? I don't mind doing the work to get it done.

    My reason for suggesting "Guid.NewGuid()" as a default is that is how the NetTiers framework functions currently (meaning existing solutions using the framework shouldn't be affected) and I agree with Swin that COMB is not a native approach and I don't believe it's right to push a 3rd party approach (e.g. non-Microsoft) in a framework claiming to be following Microsoft best practice as that's what people will be expecting to see (regardless if the approach is better).

    As for the OUTPUT clause, I have already implemented that in my local copy of the templates using a table variable and it works fine. Personally I'd prefer keeping with this approach rather than returning a rowset back to the data access layer as I'm not a fan of returning a collection of something with the assumption it always has only 1 item in it (though that approach would work better for custom procs with bulk updates perhaps). I had actually started using the OUTPUT clause to retrieve the computed columns as well, but have uncovered that the OUTPUT clause reads the newly inserted/updated/deleted record before any triggers fire. So if you have any triggers altering the record which subsequently change the computed column values, the OUTPUT clause may result in you getting differing results than you expected. I can't remember a situation where I've used a trigger in this way and would probably have to question the necessity, but that's not for me to decide and the framework shouldn't either. Therefore I'll leave the current approach for retrieving the computed values and only use the OUTPUT clause for getting newly the GUID created via NewSequentialId() (which is a shame as the OUTPUT approach was a lot more elegant than the current SELECT approach IMO). This approach will be implemented for any situation where NewSequentialId() is used, regardless of SQL 2005 features being enabled as there's no alternative really and that default is only supported in SQL 2005. I figure we're best to leave NewId() being created in the data access layer for now due to the lack of a method for cleaning retrieving a DB generated one in SQL 2000 (as it can only be accomplished via referencing an alternative key as I understand it and not easy for a code generator to figure out).

    BTW: Thanks Phil for making me aware of COMB as it has been an interesting exercise researching it. Not sure how I missed it when researching NewSequentialId() to be honest as there's the odd article out there referring to both. Even though I now think COMB is generally better (less predictability, better consolidation from multiple machines, etc) NewSequentialId() meets the requirements where we've used it so far and has the advantage of being native.

    • Post Points: 5
  • 08-28-2007 9:33 PM In reply to

    Re: Another question about defaulting to guid.empty

    swin:

    ..sheesh! I go away for a couple of days and trouble breaks out!Stick out tongue

    It's clear that you both want slighty different things and where this has happened previously we put in a new gen property that allows you to select what you want - so essentially I'm saying that Phil's last comment seems a good starting point.

    evolved - would you be able to add your requirement(code) in as an gen option i.e. NewGuidStyle - and provide options as appropriate?

    hth

    swin

    Sorry, didn't see this, but sounds like you're suggesting the same thing (albeit more concisely Smile).

    • Post Points: 5
  • 08-28-2007 10:03 PM In reply to

    Re: Suggested Solution

    And I just realised I was referencing Swin instead of Evolved. Sorry to both.

    • Post Points: 5
  • 08-29-2007 12:58 AM In reply to

    Re: Suggested Solution

    I just had a look at Phil's suggested patch and see that he's not actually using any "3rd party" library or anything. It's really just a modification to the output of Guid.NewGuid() which NetTiers was using already in place of NewId(). So I shouldn't have referred to it as an "external GUID generator" (sorry about that Phil).

    I still think it should be a conscious choice to use it though and not automatically replace NewId() or NewSequentialId() defaults so a config setting should keep everyone happy.

    • Post Points: 35
  • 08-29-2007 3:44 AM In reply to

    • PhilD
    • Top 500 Contributor
    • Joined on 08-13-2007
    • Posts 17
    • Points 475

    Re: Suggested Solution

    Thank you for your input Roger. I agree that making it a config setting would be a good idea. If I read your previous post correctly you are going to do that when you merge in your changes? I would be happy to help test it. 

    There is one thing that is confusing me, some guidance from the NetTiers team would be much appreciated. I tested my COMB patch using the generated web site and all seemed to be working well. However I have made another patch which creates a starter Windows Forms application and tried the following:

    Order order = new Order();
    OrderLine line = order.OrderLineCollection.AddNew();

    Order and OrderLine have GUIDs as the PK. They do NOT get initialised to a new COMB, they remain as Guid.Empty. It appears that the initialisation of the entity's PK is happening in the web controls layer, specifically in the xxxDataSourceControl.SetEntityKeyValues() method, not in the entities layer. This seems odd to me and was unexpected, but it seems to be a fundamental design decision made by the NetTiers team. I need to understand this in more detail.

    • Post Points: 35
  • 08-29-2007 4:22 AM In reply to

    Re: Suggested Solution

    I can certainly look at merging our 2 changes together. Not sure when I'll release it back to the NetTiers team though as I'm currently being tasked with creating a new product from scratch and "re-engineering" another and priorities seem to be shifting frequently (and one's business heavy while the other's technical heavy...). Will keep you posted if I think it will be longer than a week or two though.

    BTW, the current problem you're having with Order/OrderLine could possibly impact me too from the generated website point of view (which I wasn't planning on using in my case) so I'd be keen for that to get figured out also.

    • Post Points: 35
  • 12-11-2007 9:34 AM In reply to

    Re: Suggested Solution

    I have run into the newsequentialid() as I to need to create a disconnected pc application.  I have made changes to the latest SVN templates 677 I belive is what I start with.

    The changes I made were to do the following.

     Have Guid Columns with newsequentialid as the default be treated as Identity Rows. This allows you to do an insert with out providing the guid and have the server create the guid and return it to the Nettiers Entities. This is done using the SQL 2005 Output clause and creating a table var as is recommended by microsoft in the SQL 2005 Books Online. I will post my Patch and title it as SQL 2005 NewSequentialID Support . 

    Now its time to move on to modifiying the templates to use SQL Compact with Microsoft Sync Framework. Something tells me this will not be as easy.

     Andy

    • Post Points: 5
Page 3 of 3 (41 items) < Previous 1 2 3 | RSS
Copyright © 2008 CodeSmith Tools, LLC
Powered by Community Server (Commercial Edition), by Telligent Systems