internal DbTableBinding(Type templateType, IDbSetup setup)
            : base(templateType, setup)
        {
            var tattr = TypeHelper.TryGetAttribute <DbTableAttribute>(templateType, true);

            if (tattr != null)
            {
                TableName = setup.Naming.GetTableName(templateType, tattr.TableName);
            }

            PrimaryKey  = TypeHelper.TryGetAttribute <IDbTablePrimaryKeyAttribute>(templateType, true);
            foreignKeys = TypeHelper.GetAttributes <IDbTableForeignKeyAttribute>(templateType, true).ToList();
            uniqueKeys  = TypeHelper.GetAttributes <IDbTableUniqueKeyAttribute>(templateType, true).ToList();
            indexes     = TypeHelper.GetAttributes <IDbTableIndexAttribute>(templateType, true).ToList();

            AddColumns();
        }
        /// <summary>
        /// Scan properties and add column definition.
        /// </summary>
        private void AddColumns()
        {
            List <string> primaryKeyProps = null;
            Dictionary <Type, List <IDbColumnBinding> > foreignKeyFields = null;
            List <string> uniqueKeyProps = null;

            columns = new TypeBinding <IDbColumnBinding, DbColumnAttribute>(TemplateType,
                                                                            (p, a) => DbColumnBinding.CreateInstance(Setup, p, a, this));

            foreach (var col in columns.BindingList)
            {
                var keyConstraint = col.KeyConstraint;

                if (keyConstraint == DbKeyConstraint.PrimaryKey || keyConstraint == DbKeyConstraint.PrimaryForeignKey)
                {
                    (primaryKeyProps = primaryKeyProps ?? new List <string>()).Add(col.PropertyName);
                }

                if (keyConstraint == DbKeyConstraint.UniqueKey)
                {
                    (uniqueKeyProps = uniqueKeyProps ?? new List <string>()).Add(col.PropertyName);
                }

                if (keyConstraint == DbKeyConstraint.ForeignKey || keyConstraint == DbKeyConstraint.PrimaryForeignKey)
                {
                    foreignKeyFields = foreignKeyFields ?? new Dictionary <Type, List <IDbColumnBinding> >();
                    if (!foreignKeyFields.TryGetValue(col.PrimaryTableTemplate, out List <IDbColumnBinding> list))
                    {
                        list = new List <IDbColumnBinding>();
                        foreignKeyFields.Add(col.PrimaryTableTemplate, list);
                    }
                    list.Add(col);
                }
            }

            if (primaryKeyProps != null)
            {
                if (PrimaryKey != null)
                {
                    throw new ArgumentException($"Multiple primary key definition in table [{TableName}]");
                }

                PrimaryKey = new DbTablePrimaryKeyAttribute(primaryKeyProps.ToArray());
            }

            if (PrimaryKey?.PropertyNames.Length == 1)
            {
                SingleColumnPrimaryKey = this.FindColumn(primaryKeyProps[0]);
            }

            if (uniqueKeyProps != null)
            {
                uniqueKeys.Add(new DbTableUniqueKeyAttribute(uniqueKeyProps.ToArray()));
            }

            if (uniqueKeys?.Count == 1 && uniqueKeys[0].PropertyNames.Length == 1)
            {
                SingleColumnUniqueKey = this.FindColumn(uniqueKeys[0].PropertyNames[0]);
            }

            if (foreignKeyFields != null)
            {
                foreach (var item in foreignKeyFields)
                {
                    foreach (var rel in item.Value)
                    {
                        var attr = new DbTableForeignKeyAttribute(item.Key, rel.PropertyName);
                        foreignKeys.Add(attr);
                    }
                }
            }
        }