Welcome to the CodeSmith Community!

Re: Nhibernate assigned vs native

Template Frameworks

A description has not yet been added to this group.

Nhibernate assigned vs native

Answered (Verified) This question is answered

Blake,

Is there a way to effect what codesmith decides the key type is in Nhibernate hbm files?  I have several tables that have legacy tables that have manually generated keys and I haven't found a way to get codesmith to create the hbm files with a generator class type of assigned instead of native.  I have just been going in after the fact and manually modifing the hbm.

Thanks

dbl

  • Post Points: 35
Verified Answer
  • Yes.  I Added the following function in the NHibernateUtilities.cs file of the CodeSmith.SchemaHelper.NHibernate project :

              private static bool IsIdentity(IKey key)
              {
                  return key.Properties.Count(x => x.IsType(PropertyType.Identity)) > 0;
              }
    and changed the foreach inside PrepDestination:

                foreach (var property in entity.Key.Properties)
                {
                    PrepProperty(property);

                    property.ExtendedProperties.Add(GeneratorClass, IsIdentity(entity.Key) ? "native" : "assigned");
                }

    And it worked correctly.  Not sure why the IsType did not show up in my intelisense the first time but when I went back and tried it again is was there.

All Replies
  • Yes, Please take a look at this post for more information (community.codesmithtools.com/.../12599.aspx).

    Blake Niemyjski
    CodeSmith Tools, LLC. Software Development Engineer
    Blog: http://windowscoding.com/blogs/blake/
    .NetTiers team | Visit http://www.nettiers.net

  • Blake, two different types here.  The one referenced in the above post is the "datatype".  The key "type" I'm referring to here tells NHibernate how the key is generated.  The possibilities are things like "native", "increment", "identity", "sequence", "guid", "assigned", "foreign".

    dbl

  • Hello,

    This all takes place in the NHibernateUtilities class. Just search for "native" and "assigned" in the source.

    Blake Niemyjski
    CodeSmith Tools, LLC. Software Development Engineer
    Blog: http://windowscoding.com/blogs/blake/
    .NetTiers team | Visit http://www.nettiers.net

  • Blake can you tell me where the IsIdentity field in the below code gets its value?  The only place I can find in the provider that designates anything as IsIdentity is in the GetTableColumns and I'm not returning true for any columns in that call.

                   property.ExtendedProperties.Add(GeneratorClass, entity.Key.IsIdentity ? "native" : "assigned");

    This comes out of NHibernateUtilities.cs and the call is PrepDestination.

    Also is there a reason when populating a TableEntity object and passing in a Table object why you would call the GetTableColumns again?  When I was debugging this the GetTableColumns function on my provider gets called 3 times and at least one of them is for the same table that was passed into the TableEntity contructor.

    dbl

  • Hello,

     

    I'm not sure why it would be calling that three times. It shouldn't be / I've never seen this behavior before. I'll keep an eye out for this in the future when I'm profiling.

     

    I would do a find usages of ExtendedPropertyNames.IsIdentity. I can see an extended property is added in the GetTableColumns method on line 645 (unless I'm looking at the wrong provider). We just look up to see if a boolean extended property with this name evaluates to true, if it does we mark it as an Identity Column.

     

    This is the logic for detecting an identity column:

     

    /// <summary>

            /// Is the column an Identity column.

            /// </summary>

            /// <param name="column"></param>

            /// <returns></returns>

            public static bool IsColumnIdentity(this IDataObject column)

            {

                return (column.ExtendedProperties.Contains(Configuration.Instance.IsIdentityColumnExtendedProperty) && ((bool)column.ExtendedProperties[Configuration.Instance.IsIdentityColumnExtendedProperty].Value));

            }

     

    the IsIdentityColumn.... evaluates to the same value as ExtendedPropertyNames.IsIdentity...

     

    You could take a look in the CSLA Templates, there is a common folder with a template called SchemaHelper.cst which spits out every value of a SchemaHelper object.

    Blake Niemyjski
    CodeSmith Tools, LLC. Software Development Engineer
    Blog: http://windowscoding.com/blogs/blake/
    .NetTiers team | Visit http://www.nettiers.net

  • Well since I haven't sent you the provider for db2 I'm pretty sure you are looking at a different provider.  I'm still in a holding pattern on releasing that code to you.  The client just hasn't made a decision on that.  I have a feeling that in the TableEntity constructor its creating table objects for foreign keys and then those table objects are creating table objects for those foreign keys which is pointing back to the original table.  Only problem with that theory is that it might lead to a totally cyclical reference and I'm not seeing that.

    But on the issue of the IsIdentity property there seems to be some difference between the IsIdentity property on the "TableEntity.Key.IsIdentity" property and the extended properties for each column.  I just ran through some of my test code for my provider and loaded one of the tables I'm having the issue with.  I created a TableEntity object from a Table object and then evaluated the properties.  The Key.IsIdentity property is true but the IsIdentity extended properties for every column is false.  So the IsIdentity for the Key property must be coming from somewhere else.  here is a portion of my debug code:

            private static void DisplayTableInfo(String connString, SchemaExplorer.IDbSchemaProvider p, TableSchema table)
            {
                Debug.WriteLine("\tTable:" + table.Name);
                var cols = p.GetTableColumns(connString, table);

                CodeSmith.SchemaHelper.IEntity ce = new TableEntity(table);
                Debug.WriteLine("\t\tKey:" + ce.Key.ToString() + ", IsIdentity:" + ce.Key.IsIdentity);

                foreach (var prop in ce.Key.Properties)
                {
                    Debug.WriteLine("\t\t\tKey Prop:" + prop.Name + ", Object:" + prop.SystemType);
                }

                foreach (var prop in ce.Properties)
                {
                    Debug.WriteLine("\t\tColumn:" + prop.Name + ", Object:" + prop.SystemType);

                    foreach (var exProp in prop.ExtendedProperties)
                    {
                        Debug.WriteLine("\t\t\tExtended Prop:" + exProp.Key + ", Value:" + exProp.Value);
                    }
                }

    And here is the output from the visual studio output window.  You can see that the IsIdentity is true and the key name is "Sbinica", and if you look at the "Sbinica" column you can see that the CS_IsIdenity is false.  Am I missing something?

            Key:CodeSmith.SchemaHelper.EntityKey, IsIdentity:True
                Key Prop:Sbinica, Object:System.String
            Column:Sbinica, Object:System.String
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:
            Column:Scurrcode, Object:System.String
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:
            Column:Sbackendsystem, Object:System.String
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:
            Column:Sbanknum, Object:System.String
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:
            Column:Sreportgroup, Object:System.String
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:
            Column:Smerchsystem, Object:System.String
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:
            Column:Stranssystem, Object:System.String
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:
            Column:Sprocessinggroup, Object:System.String
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:
            Column:Bfxindicator, Object:System.String
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:
            Column:Sbackendmerchsys, Object:System.String
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:
            Column:Sregion, Object:System.String
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:
            Column:Scountry, Object:System.String
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:
            Column:Sinsertflags, Object:System.String
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:
            Column:Sprocessflags, Object:System.String
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:
            Column:Sassociation, Object:System.String
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:
            Column:Sshortdescription, Object:System.String
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:
            Column:Soutboundflags, Object:System.String
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:
            Column:Sworkcenter, Object:System.String
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:
            Column:Irespondbydays, Object:System.Int32
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:
            Column:Stype, Object:System.String
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:
            Column:Srulesspecifier, Object:System.String
                Extended Prop:CS_IsIdentity, Value:False
                Extended Prop:CS_Description, Value:

    Thanks
     
    dbl

  • Hello,

    SchemaHelper builds up each table object and properties and once every entity has been created, the Entity Provider calls initialize on each entity which then creates the associations (and uses the existing entities instead of creating new ones for each relationship).

    Yeah, there is a slight difference in the EntityKey calculation (note: The Association property will be removed in the future as it is not needed):

     

            public bool IsIdentity
            {
                get { return !IsComposite; /* && (Properties.Count(x => !x.IsIdentity) == 0));*/ }
            }
    
            public bool IsComposite
            {
                get { return (Properties.Count + Associations.Count > 1); }
            }
    
    
    This could be converted to:
                get { return Properties.Count(x => !x.IsType(PropertyType.Identity)) == 0)) }
    
    
    but I'll need to do more research on what this is going to effect. There was a huge refactor job to make this all simplistic and another dev jumped in and really changed this :\

    Blake Niemyjski
    CodeSmith Tools, LLC. Software Development Engineer
    Blog: http://windowscoding.com/blogs/blake/
    .NetTiers team | Visit http://www.nettiers.net

  • So the only place where this code is being used is within the nHibernateUtilities.cs . If you update the references to this: entity.Key.IsIdentity  with a quick work around as proposed above. Can you please verify that the logic I proposed is correct. If it is, I'll go a head and make this change.

    Blake Niemyjski
    CodeSmith Tools, LLC. Software Development Engineer
    Blog: http://windowscoding.com/blogs/blake/
    .NetTiers team | Visit http://www.nettiers.net

  • Blake,

    Am I missing something or is the code you are talking about commented out and IsIdentity is just a "Not IsComposite"?
     
    dbl
  • Also,

    I don't see an IsType function on any of the objects  so I wrote my own.  I included the following two functions in the NHibernateUtilities.cs file

              private static bool IsIdentity(IKey key)
              {
                  return key.Properties.Count(x => IsType(x, PropertyType.Identity)) > 0;
              }

             private static bool IsType(IProperty prop, PropertyType propType)
             {
                 return (prop.PropertyType == propType);
             }

    And then changed out the call that uses entity.key.IsIdentity() too look like this.

                    property.ExtendedProperties.Add(GeneratorClass, IsIdentity(entity.Key) ? "native" : "assigned");

    Please notice that I removed the "!"(NOT) operator and change the evaluation to "> 0".  I think this reads better and although I don't think this call will get made when there is more than one property in the collection if it does it would be fewer operations. 

    I didn't see a better way to implement this as I don't have access to the SchemaHelper source.

    dbl
  • Yes, the current code is just checking !Composite, my change is detailed below that. Did your change work as expected? Also you can do prop.IsType(PropertyType)

    Blake Niemyjski
    CodeSmith Tools, LLC. Software Development Engineer
    Blog: http://windowscoding.com/blogs/blake/
    .NetTiers team | Visit http://www.nettiers.net

  • Yes.  I Added the following function in the NHibernateUtilities.cs file of the CodeSmith.SchemaHelper.NHibernate project :

              private static bool IsIdentity(IKey key)
              {
                  return key.Properties.Count(x => x.IsType(PropertyType.Identity)) > 0;
              }
    and changed the foreach inside PrepDestination:

                foreach (var property in entity.Key.Properties)
                {
                    PrepProperty(property);

                    property.ExtendedProperties.Add(GeneratorClass, IsIdentity(entity.Key) ? "native" : "assigned");
                }

    And it worked correctly.  Not sure why the IsType did not show up in my intelisense the first time but when I went back and tried it again is was there.

  • Hello,

    This has been fixed in the latest nightly build.

    Blake Niemyjski
    CodeSmith Tools, LLC. Software Development Engineer
    Blog: http://windowscoding.com/blogs/blake/
    .NetTiers team | Visit http://www.nettiers.net

Page 1 of 1 (14 items)