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
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.
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.com
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".
Hello,
This all takes place in the NHibernateUtilities class. Just search for "native" and "assigned" in the source.
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.
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.
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 :\
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 :\
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 :\
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.
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)
This has been fixed in the latest nightly build.