In past projects I've used guids as primary keys and things have went well. The new project uses integers and I've been able to work around them until now. I just hit a brick wall. I'm hoping there is a way around, but I don't see it.
Objects:
Editable Root List
Editable Root
Editable Child List
Editable Child
Okay. All of these objects use integers as primary keys (a identity generated integer from the database). When a new object is created I set the ID to -1. Then during the save process I return the identity key field from MSSQL with an output paramter and then I've got my real ID! Here is the problem my root item has a reference to a 'Primary Child Item'. The only problem is that if the child item is new, my primarychilditemID property will be a -1. How do I deal with this? I hope this explains what I'm doing.
CSLA IDs needs to be unique with in the collection. I used this class to generate IDs for objects not fetched from a data source. The idea is simple, and that is to generate decrementing ID that is unique. I then replace the object ID with the id generated by the DB after insert.
Imports
System.ThreadingFriend
Class IDGenerator Private Shared ID As Integer = -1 Private Sub New() End Sub Public Shared Function GetNextID() As Integer Return System.Threading.Interlocked.Decrement(ID) End FunctionEnd
Class
This is how my Codesmith templates generate the Update part of a child BO that needs the parent Integer key for the Insert to the DB. Notice how the ParentBO is passed to the child collection as a Parameter which then passes it to each child.
Protected Friend Overridable Sub Update(ByVal tr As IDbTransaction, ByVal ParentBO As ParentBO ) If Not Me.IsDirty ThenJoe
Matt,
I came to the same conclusion. I'm trying to get permission to convert over to guids. The project is still being developed at this point. Thanks.
Another thing to consider is this: the only thing CSLA requires is that GetIdValue() return a unique value for your object.
That value does not have to be a real value!
In other words, you do not have to return your object's real ID value from GetIdValue(). You could return some arbitrary value (int, guid, whatever) that is never stored in the database or used for any other purpose beyond providing a unique ID for your object in memory.
The value of using a real ID value is that the ToString(), GetHashCode() and Equals() overloads provided by BusinessBase then operate on your real ID. But in a great many cases (most?), you don't care if GetHashCode() returns the same value every time your object is loaded from the database. You only care that it is unique at any given instant in time.
ToString() may be a bigger deal, because you probably want it to return something real. So if you do use an arbitrary (non-meaningful) ID value for GetIdValue(), then you'd probably need to override ToString() in each business class to return some meaningful string value.
I sometimes do create a private, unique, non-meaningful ID value just for GetIdValue() - especially if I don't know or care about the real ID value that will ultimately be in the database. Or sometimes I have objects that never do have real unique ID values, or which have very complex compound unique IDs that would be hard or expensive to merge into a value for GetIdValue(). To avoid that complexity, I'll just create an arbitrary int or guid value for every object, new or old, and return it from GetIdValue() - even though that arbitrary value is only used in memory and has no real meaning in the database or anything else.
Copyright (c) Marimer LLC