Example #1
0
        internal static XElement GetSimplePropertyHbmXml(ColumnMetadata entry, string xElementName)
        {
            if (entry == null)
            {
                return(null);
            }
            if (string.IsNullOrWhiteSpace(xElementName))
            {
                xElementName = Globals.HbmXmlNames.PROPERTY;
            }
            if (string.IsNullOrWhiteSpace(entry.data_type) &&
                Sorting.DbContainers.AllColumns.Data.Any(
                    x => string.Equals(x.column_name, entry.constraint_name, Sorting.C)))
            {
                var acEntry =
                    Sorting.DbContainers.AllColumns.Data.First(
                        x => string.Equals(x.column_name, entry.constraint_name, Sorting.C));
                entry.CopyFrom(acEntry);
            }
            else
            {
                entry.CopyFrom(Sorting.GetFromAllColumnMetadata(entry));
            }

            var simplePropName   = Compose.PropertyName(entry.column_name);
            var simplePropColumn = NfString.ExtractLastWholeWord(entry.column_name, null);

            var simplePropDataType = Globals.HbmXmlNames.ANSI_STRING;

            if (!Util.Lexicon.DotNet2HbmTypes.ContainsKey(string.Format("{0}", entry.data_type)) &&
                !Util.Lexicon.Mssql2HbmTypes.ContainsKey(string.Format("{0}", entry.data_type)))
            {
                Console.WriteLine("{0:yyyy-MM-dd HH:mm:ss.ffff} '{1}' has no matching type in the Lexicon [{2}].",
                                  DateTime.Now,
                                  entry.data_type, entry.ToJsonString());
            }
            else
            {
                simplePropDataType = entry.data_type.StartsWith("System.")
                    ? Util.Lexicon.DotNet2HbmTypes[entry.data_type]
                    : Util.Lexicon.Mssql2HbmTypes[entry.data_type];
            }

            var simplePropLen = simplePropDataType == Globals.HbmXmlNames.ANSI_STRING
                ? entry.string_length == null || entry.string_length <= 0 ? Globals.MSSQL_MAX_VARCHAR : entry.string_length
                : null;

            if (simplePropDataType == typeof(Boolean).Name)
            {
                if (simplePropName.StartsWith(NfString.DefaultNamePrefix))
                {
                    simplePropName = simplePropName.Remove(0, NfString.DefaultNamePrefix.Length);
                }
                simplePropName = "Is" + simplePropName;
            }

            return(XeFactory.PropertyNode(xElementName, simplePropName, simplePropColumn,
                                          simplePropDataType, simplePropLen.ToString(), entry.is_nullable.HasValue && entry.is_nullable == true,
                                          entry.ToJsonString()));
        }
Example #2
0
        private EfSimpleProp GetSimpleProp(string propName)
        {
            var propColMetadataList = GetColumnDataByPropertyName(propName);

            if (propColMetadataList == null || propColMetadataList.Length <= 0)
            {
                return(null);
            }
            var propColMetadata = propColMetadataList.First();

            var isString = false;

            if (!_efProperties.ContainsKey(propName) && Util.Lexicon.Mssql2HbmTypes.ContainsKey(propColMetadata.data_type))
            {
                isString = Util.Lexicon.Mssql2HbmTypes[propColMetadata.data_type] == "AnsiString";
            }
            else
            {
                isString = _efProperties[propName] == "string";
            }
            var efsprop = new EfSimpleProp {
                IsString = isString
            };

            efsprop.IsUnicode         = efsprop.IsString && propColMetadata.data_type.StartsWith("n");
            efsprop.ColumnName        = NfString.ExtractLastWholeWord(propColMetadata.column_name.Replace("[", string.Empty).Replace("]", string.Empty), null);
            efsprop.RequiresPrecision = Globals.MssqlTypesWithPrecision.Contains(propColMetadata.data_type);
            //this exports doubled when it is unicode
            efsprop.StringLength = GetStringLength(propColMetadata.string_length, efsprop.IsUnicode);
            efsprop.Precision    = propColMetadata.precision;
            efsprop.PropName     = propName;
            return(efsprop);
        }
Example #3
0
        public static string ManyToOnePropertyName(string fullAssemblyQualTypeName, string[] fkColumnNames)
        {
            var fkPropertyType = new NfTypeName(fullAssemblyQualTypeName);

            var fkPropertyName = fkPropertyType.ClassName;

            fkColumnNames = fkColumnNames.Select(x => NfString.CapWords(NfString.ExtractLastWholeWord(x, '.'), null)).ToArray();
            return(string.Format("{0}By{1}", fkPropertyName,
                                 string.Join("And", fkColumnNames)));
        }
Example #4
0
        /// <summary>
        /// Gets a type&apos;s name less the namespace
        /// </summary>
        /// <param name="simplePropType"></param>
        /// <returns></returns>
        public static string GetTypeNameWithoutNamespace(string simplePropType)
        {
            if (String.IsNullOrWhiteSpace(simplePropType))
            {
                return(null);
            }

            if (!simplePropType.Contains(NfSettings.DefaultTypeSeparator))
            {
                return(simplePropType);
            }

            if (simplePropType.Contains(Constants.TYPE_METHOD_NAME_SPLIT_ON))
            {
                simplePropType = simplePropType.Substring(0,
                                                          simplePropType.IndexOf(Constants.TYPE_METHOD_NAME_SPLIT_ON, StringComparison.Ordinal));
            }

            return(NfString.ExtractLastWholeWord(simplePropType, NfSettings.DefaultTypeSeparator));
        }
Example #5
0
        internal static void GetSimpleId(ColumnMetadata pkId, XElement classXe)
        {
            pkId.CopyFrom(Sorting.GetFromAllColumnMetadata(pkId));
            var fullColumnName = pkId.column_name;

            Compose.ValidSplit(fullColumnName, 3);
            var          columnName   = NfString.ExtractLastWholeWord(fullColumnName, null);
            const string propertyName = Globals.HbmXmlNames.ID;
            var          type         = Util.Lexicon.Mssql2HbmTypes[(pkId.data_type)];
            var          length       = pkId.string_length ?? Globals.MSSQL_MAX_VARCHAR;
            XElement     idXe;

            //don't let the '-1' from the database make it to the hbm.xml's
            if (string.Equals(type, Globals.HbmXmlNames.ANSI_STRING))
            {
                if (length <= 0)
                {
                    length = Globals.MSSQL_MAX_VARCHAR;
                }
                idXe = XeFactory.IdNode(propertyName, columnName, type,
                                        length.ToString(CultureInfo.InvariantCulture), pkId.ToJsonString());
            }
            else
            {
                idXe = XeFactory.IdNode(propertyName, columnName, type, pkId.ToJsonString());
            }

            //simple split of assigned or is_identity
            XElement generatorXe;

            if (pkId.is_auto_increment.HasValue && pkId.is_auto_increment.Value)
            {
                generatorXe = XeFactory.GeneratorId(Globals.HbmXmlNames.IDENTITY);
            }
            else
            {
                generatorXe = XeFactory.GeneratorId(Globals.HbmXmlNames.ASSIGNED);
            }
            idXe.Add(generatorXe);
            classXe.Add(idXe);
        }
Example #6
0
        public Ef35PropertyAttr(ColumnMetadata md, bool addUpdateCheckNever)
        {
            Name          = NfString.ExtractLastWholeWord(md.column_name, Shared.Core.NfSettings.DefaultTypeSeparator);
            _composedName = Compose.PropertyName(md.column_name);
            DbType        = md.data_type.ToUpper();

            if (Lexicon.Mssql2HbmTypes.ContainsKey(md.data_type) && Lexicon.Mssql2HbmTypes[md.data_type] == "AnsiString")
            {
                if (md.string_length != null && md.string_length < 0)
                {
                    DbType = string.Format("{0}(MAX)", DbType);
                }
                else
                {
                    DbType = string.Format("{0}({1})", DbType, md.string_length);
                }
            }
            if (Globals.MssqlTypesWithPrecision.Contains(md.data_type))
            {
                DbType = string.Format("{0}({1})", DbType, md.precision);
            }

            if (md.is_nullable != null && md.is_nullable.Value == false)
            {
                DbType    = string.Format("{0} NOT NULL", DbType);
                CanBeNull = false;
            }
            else
            {
                CanBeNull = true;
            }

            if (md.is_auto_increment != null && md.is_auto_increment.Value)
            {
                DbType        = string.Format("{0} IDENTITY", DbType);
                IsPrimaryKey  = true;
                IsDbGenerated = true;
            }
            IsUpdateCheckNever = addUpdateCheckNever;
        }
Example #7
0
 public static string PropertyName(string name, bool replaceInvalidsWithHexEsc = false)
 {
     name = NfString.ExtractLastWholeWord(name, Shared.Core.NfSettings.DefaultTypeSeparator);
     name = NfString.CapWords(name, null);
     return(NfString.SafeDotNetIdentifier(name, replaceInvalidsWithHexEsc));
 }
Example #8
0
        /// <summary>
        /// Produces a single hbm.xml for the given <see cref="tbl"/>
        /// </summary>
        /// <param name="outputNamespace"></param>
        /// <param name="tbl"></param>
        /// <returns>The path the generated hbm.xml file</returns>
        public static string GetSingleHbmXml(string outputNamespace, string tbl)
        {
            if (HbmKeys == null || HbmOneToMany == null || HbmBags == null)
            {
                throw new RahRowRagee("Assign the static variables HbmKeys, HbmOneToMany and HbmBags" +
                                      " then try again (These values are calculated from Sorting).");
            }
            if (Settings.DoNotReference.Contains(tbl))
            {
                return(null);
            }

            var hbmPk   = HbmKeys.Data;
            var hbmFk   = HbmOneToMany.Data;
            var hbmBags = HbmBags.Data;

            //possiable duplicate names handled within this
            var className = Compose.ClassName(tbl, outputNamespace);

            //not having the naming pattern is exceptional
            Compose.ValidSplit(tbl, 2);

            var tableName  = NfString.ExtractLastWholeWord(tbl, null);
            var schemaName = tbl.Replace(string.Format(".{0}", tableName), string.Empty);

            var xe = XeFactory.HibernateMappingNode();

            var classXe = XeFactory.ClassNode(className, tableName, schemaName);

            var hasNoPkAtAll = GetPk(outputNamespace, tbl, hbmPk, classXe);

            //having no pk, add the contrived comp-key to the class
            if (hasNoPkAtAll)
            {
                GetAllColumnsAsCompositeKey(tbl, classXe, outputNamespace);
            }
            else//simple properties
            {
                foreach (var columnName in Sorting.DbContainers.FlatData.Data.Where(x => string.Equals(x.table_name, tbl, Sorting.C)))
                {
                    var fullColumnName = columnName.column_name;
                    Compose.ValidSplit(fullColumnName, 3);
                    var simplePropXe = GetSimplePropertyHbmXml(columnName, Globals.HbmXmlNames.PROPERTY);
                    classXe.Add(simplePropXe);
                }
            }

            GetFksWhichAreNotPartOfPks(outputNamespace, tbl, hbmFk, classXe);

            GetBags(outputNamespace, tbl, hbmBags, hasNoPkAtAll, className, classXe);

            xe.Add(classXe);

            var hbmXmlOutputPath = Path.Combine(Settings.HbmDirectory,
                                                Compose.HbmFileName(tbl));
            var xmlContent = xe.ToString()
                             .Replace("<hibernate-mapping>", "<hibernate-mapping xmlns=\"urn:nhibernate-mapping-2.2\">");

            File.WriteAllText(hbmXmlOutputPath, xmlContent);

            //perform rename of any properties which match classname or are duplicated therein
            CorrectHbmXmlDuplicateNames(hbmXmlOutputPath);
            return(hbmXmlOutputPath);
        }
Example #9
0
        /// <summary>
        /// Produces a single hbm.xml with the sql-query node in tow.
        /// </summary>
        /// <param name="outputNamespace"></param>
        /// <param name="storedProc"></param>
        /// <returns>The path to the generated hbm.xml file.</returns>
        public static string GetHbmNamedQueryXml(string outputNamespace, string storedProc)
        {
            if (Sorting.AllStoredProcNames == null || Sorting.AllStoredProcNames.Count <= 0)
            {
                throw new RahRowRagee("There doesn't appear to be any stored procs here.");
            }

            if (Settings.DoNotReference.Contains(storedProc) || !Sorting.AllStoredProx.ContainsKey(storedProc))
            {
                return(null);
            }

            var sp = Sorting.AllStoredProx[storedProc];

            if (sp == null)
            {
                return(null);
            }

            var returnedData = sp.ReturnedData;

            if (returnedData == null || returnedData.Count <= 0)
            {
                return(null);
            }

            if (returnedData.Keys.Count <= 0)
            {
                Settings.WriteToStoredProcLog(string.Format("Stored proc named '{0}' has an empty dataset", sp.ProcName));
                if (!Sorting.EmptyDatasetProx.Contains(sp.ProcName))
                {
                    Sorting.EmptyDatasetProx.Add(sp.ProcName);
                }
                return(null);
            }

            //both the return types and the callable sql-query are wrapped in this root node
            var xe = XeFactory.HibernateMappingNode();

            if (returnedData.Count > 1)
            {
                Settings.WriteToStoredProcLog(string.Format("Stored Proc named '{0}' returns a multi-table dataset", storedProc));
                if (!Sorting.MultiTableDsProx.Contains(storedProc))
                {
                    Sorting.MultiTableDsProx.Add(storedProc);
                }
            }

            //possiable duplicate names handled within this
            var className = Compose.ClassName(string.Format("{0}.{1}{2}", Globals.STORED_PROX_FOLDER_NAME, storedProc, "Table"), outputNamespace);

            var classXe = XeFactory.ClassNode(className, null, null);

            classXe.Add(XeFactory.IdNode(null));

            var sqlQryName = NfString.SafeDotNetIdentifier(storedProc);
            var returnsXe  = XeFactory.ReturnNode(sqlQryName, className);

            foreach (var cMeta in returnedData[returnedData.Keys.First()])
            {
                var simplePropName     = Compose.PropertyName(cMeta.column_name, true);
                var simplePropColumn   = NfString.ExtractLastWholeWord(cMeta.column_name, null);
                var simplePropDataType = Util.Lexicon.DotNet2HbmTypes[cMeta.data_type];

                classXe.Add(XeFactory.PropertyNode(Globals.HbmXmlNames.PROPERTY, simplePropName, null, simplePropDataType,
                                                   (cMeta.data_type == "System.String"
                        ? Globals.MSSQL_MAX_VARCHAR.ToString(CultureInfo.InvariantCulture)
                        : null), cMeta.is_nullable.HasValue && cMeta.is_nullable == true, string.Empty));

                returnsXe.Add(XeFactory.ReturnPropertyNode(simplePropColumn, simplePropName));
            }

            var sqlQryXe = XeFactory.SqlQueryNode(sqlQryName);

            sqlQryXe.Add(returnsXe);

            sqlQryXe.Add(new XCData(sp.ToHbmSql()));

            xe.Add(classXe);
            xe.Add(sqlQryXe);

            var hbmXmlOutputPath = Path.Combine(Settings.HbmStoredProcsDirectory,
                                                Compose.HbmFileName(storedProc.Replace(" ", Globals.REPLACE_SPACE_WITH_SEQUENCE)));
            var xmlContent = xe.ToString()
                             .Replace("<hibernate-mapping>", "<hibernate-mapping xmlns=\"urn:nhibernate-mapping-2.2\">");

            File.WriteAllText(hbmXmlOutputPath, xmlContent);
            CorrectHbmXmlDuplicateNames(hbmXmlOutputPath, true);
            return(hbmXmlOutputPath);
        }
Example #10
0
        protected static void GetFksWhichAreNotPartOfPks(string outputNamespace, string tbl, Dictionary <string, FkItem> hbmFk, XElement classXe)
        {
            //----fks which are not part of pks
            if (!hbmFk.ContainsKey(tbl))
            {
                return;
            }
            var tblFks = hbmFk[tbl].ManyToOne;

            foreach (var fkName in tblFks.Keys)
            {
                //these would be FK ref to another type but its underlying table is excluded so now its just a bunch of value types
                if (Settings.DoNotReference.Contains(fkName))
                {
                    foreach (var reducedFk in tblFks[fkName])
                    {
                        var reducedFkSimpProp = GetSimplePropertyHbmXml(reducedFk,
                                                                        Globals.HbmXmlNames.PROPERTY);
                        classXe.Add(reducedFkSimpProp);
                    }
                    continue; //these need representation but not as class types
                }

                var manytoOneColumns = new List <ColumnMetadata>();
                if (!HbmOneToMany.GetManyToOneColumns(tbl, ref manytoOneColumns))
                {
                    continue;
                }

                var fkColumnsByDistinctConstraintName = manytoOneColumns.Select(x => x.constraint_name).Distinct().ToList();
                foreach (var distinctConstraintName in fkColumnsByDistinctConstraintName)
                {
                    var dMtoColumnData = tblFks[fkName].Where(
                        x =>
                        string.Equals(x.constraint_name, distinctConstraintName, Sorting.C)).ToList();

                    if (dMtoColumnData.Count <= 0)
                    {
                        continue;
                    }
                    var fkColumnXes   = new List <XElement>();
                    var fkColumnNames = new List <string>();
                    foreach (var x in dMtoColumnData)
                    {
                        x.CopyFrom(Sorting.GetFromAllColumnMetadata(x));
                        var fullColumnName = x.column_name;

                        Compose.ValidSplit(fullColumnName, 3);
                        var cn = NfString.ExtractLastWholeWord(fullColumnName, null);

                        //need to store these temp, since we are also drafting thier parent's name
                        fkColumnXes.Add(XeFactory.ColumnNode(cn, x.ToJsonString()));
                        fkColumnNames.Add(cn);
                    }

                    var fkPropertyType = new NfTypeName(Compose.ClassName(fkName, outputNamespace));
                    var fkPropertyName = Compose.ManyToOnePropertyName(Compose.ClassName(fkName, outputNamespace),
                                                                       fkColumnNames.ToArray());

                    var manyToOneXe = XeFactory.ManyToOneNode(fkPropertyName, fkPropertyType.AssemblyQualifiedName);
                    foreach (var fkXe in fkColumnXes)
                    {
                        manyToOneXe.Add(fkXe);
                    }

                    classXe.Add(manyToOneXe);
                }
            }
        }
Example #11
0
        protected static void GetBags(string outputNamespace, string tbl, Dictionary <string, List <ColumnMetadata> > hbmBags, bool hasNoPkAtAll,
                                      string className, XElement classXe)
        {
            //----hbm bags
            var hbmBagNames = new List <string>(); //check for duplicates

            if (Settings.DoNotReference.Contains(tbl) || !hbmBags.ContainsKey(tbl) || hasNoPkAtAll)
            {
                return;
            }
            var distinctBagConstraintNames = hbmBags[tbl].Select(x => x.constraint_name).Distinct().ToList();

            foreach (var distinctBagConstraintName in distinctBagConstraintNames)
            {
                var hbmBagPropertyName = Compose.PropertyName(distinctBagConstraintName);
                var hbmBagXe           = XeFactory.BagNode(hbmBagPropertyName, Globals.HbmXmlNames.ALL_DELETE_ORPHAN,
                                                           bool.TrueString.ToLower(), bool.TrueString.ToLower(),
                                                           Globals.REPRESENT_512);
                var bagColumns =
                    hbmBags[tbl].Where(x => string.Equals(x.constraint_name, distinctBagConstraintName, Sorting.C))
                    .Select(x => x.column_name)
                    .ToList();

                string hbmOneToMany;
                if (bagColumns.Count > 1)
                {
                    var hbmBagFirstKey =
                        hbmBags[tbl].First(
                            x => string.Equals(x.constraint_name, distinctBagConstraintName, Sorting.C));
                    if (Settings.DoNotReference.Contains(hbmBagFirstKey.table_name))
                    {
                        continue;
                    }
                    hbmOneToMany = Compose.ClassName((hbmBagFirstKey.table_name), outputNamespace);
                    var hbmBagFkKeyXe = XeFactory.KeyNodeClassName(className);

                    foreach (
                        var columnData in
                        hbmBags[tbl].Where(
                            x => string.Equals(x.constraint_name, distinctBagConstraintName, Sorting.C)).ToList())
                    {
                        columnData.CopyFrom(Sorting.GetFromAllColumnMetadata(columnData));
                        var fullColumnName = columnData.column_name;

                        Compose.ValidSplit(fullColumnName, 3);
                        var hbmBagKeyColumn = NfString.ExtractLastWholeWord(fullColumnName, null);

                        var hbmBagKeyXe = XeFactory.ColumnNode(hbmBagKeyColumn, columnData.ToJsonString());
                        hbmBagFkKeyXe.Add(hbmBagKeyXe);
                    }

                    hbmBagXe.Add(hbmBagFkKeyXe);
                }
                else
                {
                    var hbmBagFirstKey =
                        hbmBags[tbl].First(
                            x => string.Equals(x.constraint_name, distinctBagConstraintName, Sorting.C));
                    if (Settings.DoNotReference.Contains(hbmBagFirstKey.table_name))
                    {
                        continue;
                    }

                    hbmBagFirstKey.CopyFrom(Sorting.GetFromAllColumnMetadata(hbmBagFirstKey));
                    var fullColumnName = hbmBagFirstKey.column_name;
                    hbmOneToMany = Compose.ClassName((hbmBagFirstKey.table_name), outputNamespace);

                    Compose.ValidSplit(fullColumnName, 3);

                    var hbmBagKeyColumn = NfString.ExtractLastWholeWord(fullColumnName, null);
                    var hbmBagKeyXe     = XeFactory.KeyNodeColumnName(hbmBagKeyColumn, hbmBagFirstKey.ToJsonString());
                    hbmBagXe.Add(hbmBagKeyXe);
                }

                var hbmOneToManyXe = XeFactory.OneToManyNode(hbmOneToMany);
                hbmBagXe.Add(hbmOneToManyXe);

                //attempt to make the name plural
                var newBagName = Compose.BagPropertyName(hbmOneToMany);
                hbmBagXe.FirstAttribute.SetValue(newBagName);

                classXe.Add(hbmBagXe);

                hbmBagNames.Add(hbmBagPropertyName);
            }
        }
Example #12
0
        protected static bool GetPk(string outputNamespace, string tbl, Dictionary <string, PkItem> hbmPk, XElement classXe)
        {
            //----PK
            var pkId         = hbmPk.ContainsKey(tbl) ? hbmPk[tbl].Id : null;
            var hasNoPkAtAll = !hbmPk.ContainsKey(tbl);

            if (pkId == null && !hasNoPkAtAll)
            {
                var          compClassName    = Compose.CompKeyClassName(tbl, outputNamespace);
                const string compPropertyName = Globals.HbmXmlNames.ID;
                var          compKeyXe        = XeFactory.CompositeIdNode(compPropertyName, compClassName);

                //key-many-to-one
                var hbmKeyManyToOne = hbmPk[tbl].KeyManyToOne ?? new Dictionary <string, List <ColumnMetadata> >();
                if (hbmKeyManyToOne.Count > 0)
                {
                    foreach (var keyname in hbmKeyManyToOne.Keys.Where(k => !Settings.DoNotReference.Contains(k)))
                    {
                        //need to iterate here on a per 'constraint_name', the json data-struct misses this
                        //eg a table, 4 columns; 2 are comp to another table's Pk and the other 2 are also a comp the SAME table's PK
                        var keyManytoOneColumns = new List <ColumnMetadata>();
                        if (!HbmKeys.GetKeyManyToOneColumns(tbl, ref keyManytoOneColumns))
                        {
                            continue;
                        }
                        foreach (var distinctColumn in keyManytoOneColumns.Distinct(new ConstraintNameComparer()))
                        {
                            var dKmtoCName = distinctColumn.constraint_name;
                            var keyMtoFullyQualTypeName = Compose.ClassName(keyname, outputNamespace);
                            var keyMtoNfTypeNameObj     = new NfTypeName(keyMtoFullyQualTypeName);
                            var keyMtoSimpleName        = keyMtoNfTypeNameObj.ClassName;

                            var keyMtoXe = XeFactory.KeyManyToOneNode(keyMtoSimpleName,
                                                                      keyMtoFullyQualTypeName);

                            var dKmtoColumnData = hbmKeyManyToOne[keyname].Where(
                                x =>
                                string.Equals(x.constraint_name, dKmtoCName, Sorting.C)).ToList();

                            if (dKmtoColumnData.Count <= 0)
                            {
                                continue;
                            }

                            foreach (var kmtoColumn in dKmtoColumnData)
                            {
                                kmtoColumn.CopyFrom(Sorting.GetFromAllColumnMetadata(kmtoColumn));
                                var fullColumnName = kmtoColumn.column_name;

                                //not having the naming pattern is exceptional
                                Compose.ValidSplit(fullColumnName, 3);

                                var keyMtoColumnXe =
                                    XeFactory.ColumnNode(NfString.ExtractLastWholeWord(fullColumnName, null),
                                                         kmtoColumn.ToJsonString());

                                keyMtoXe.Add(keyMtoColumnXe);
                            }

                            compKeyXe.Add(keyMtoXe);
                        } //end foreach distinct constraintname
                    }
                }         //end key-many-to-one

                var hbmKeyProperty = hbmPk[tbl].KeyProperty ?? new Dictionary <string, List <ColumnMetadata> >();

                //these would have been added as key-many-to-one, but thier underlying table has been excluded.
                foreach (var reduced in hbmKeyManyToOne.Where(k => Settings.DoNotReference.Contains(k.Key)))
                {
                    foreach (var redux in reduced.Value)
                    {
                        redux.CopyFrom(Sorting.GetFromAllColumnMetadata(redux));
                    }
                    //insure they got everything for being a value type

                    hbmKeyProperty.Add(reduced.Key, reduced.Value);
                }

                if (hbmKeyProperty.Count > 0)
                {
                    //Dictionary<string, List<ColumnMetadata>>
                    foreach (var keyName in hbmKeyProperty.Keys)
                    {
                        //SPECIAL NOTE: the original PS code seemed to imply that a key-property is always just one column...
                        var keyPropJsonData = hbmKeyProperty[keyName].FirstOrDefault();
                        if (keyPropJsonData == null)
                        {
                            continue;
                        }

                        keyPropJsonData.CopyFrom(Sorting.GetFromAllColumnMetadata(keyPropJsonData));
                        var keyPropPropertyName = Compose.PropertyName(keyPropJsonData.column_name);
                        var fullcolumnName      = keyPropJsonData.column_name;

                        Compose.ValidSplit(fullcolumnName, 3);

                        var keyPropDataType = Util.Lexicon.Mssql2HbmTypes[(keyPropJsonData.data_type)];
                        var keyPropColumn   = NfString.ExtractLastWholeWord(fullcolumnName, null);
                        var keyPropLen      = keyPropJsonData.string_length ?? Globals.MSSQL_MAX_VARCHAR;

                        if (string.Equals(keyPropDataType, Globals.HbmXmlNames.ANSI_STRING))
                        {
                            if (keyPropLen <= 0)
                            {
                                keyPropLen = Globals.MSSQL_MAX_VARCHAR;
                            }
                            var keyPropXe = XeFactory.KeyPropertyNode(keyPropPropertyName, keyPropColumn,
                                                                      keyPropDataType, keyPropLen.ToString(CultureInfo.InvariantCulture),
                                                                      keyPropJsonData.ToJsonString());
                            compKeyXe.Add(keyPropXe);
                        }
                        else
                        {
                            var keyPropXe = XeFactory.KeyPropertyNode(keyPropPropertyName, keyPropColumn,
                                                                      keyPropDataType, keyPropJsonData.ToJsonString());
                            compKeyXe.Add(keyPropXe);
                        }
                    }
                }
                classXe.Add(compKeyXe);
            }
            else if (pkId != null)
            {
                GetSimpleId(pkId, classXe);
            } //end PK
            return(hasNoPkAtAll);
        }