public void RuntimeAddingAttributte() { try { var type = MembersHandler.AddAttribute( "RuntimeAssembly", typeof(Types.Table2Type), new MembersHandler.RuntimeAttributeInfo( typeof(CommentaryAttribute), "TestCommentary"), new MembersHandler.RuntimeAttributeInfo( typeof(MySqlDBTypeOverrideAttribute), MySqlDbType.VarChar)); bool result = MembersHandler.HasAttribute <CommentaryAttribute>(type); result &= MembersHandler.HasAttribute <MySqlDBTypeOverrideAttribute>(type); Assert.IsTrue(result); } catch (Exception ex) { Assert.Fail(ex.Message); } }
/// <summary> /// Generate init string from contrains related to this column. /// Can auto detect modifers. /// </summary> /// <param name="member">Member that would be used to looking for descriptors.</param> /// <param name="selfTableName">Name of holding table.</param> /// <returns>Generated SQL command.</returns> public static string ConstrainDeclarationCommand(MemberInfo member, string selfTableName) { // Looking for column and FK definitions. if (!MembersHandler.TryToGetAttribute <ColumnAttribute>(member, out ColumnAttribute column) || !MembersHandler.TryToGetAttribute <IsForeignKeyAttribute>(member, out IsForeignKeyAttribute isForeignKey)) { // Deop if not defined. return(""); } //// Try to find overriding attribute. //if (Modifiers.DBPathOverride.TryToGetValidOverride<Column>( // member, // out Modifiers.DBPathOverride columnOverrider)) //{ // column.title = columnOverrider.column ?? column.title; //} // Try to find overriding attribute. if (Modifiers.DBPathOverrideAttribute.TryToGetValidOverride <IsForeignKeyAttribute>( member.DeclaringType, out Modifiers.DBPathOverrideAttribute fkOverrider)) { // Override fields. isForeignKey.schema = fkOverrider.schema ?? isForeignKey.schema; isForeignKey.table = fkOverrider.table ?? isForeignKey.table; isForeignKey.column = fkOverrider.column ?? isForeignKey.column; } return(ConstrainDeclarationCommand(column, isForeignKey, selfTableName)); }
/// <summary> /// Trying to find member with defined IsAutoIncrement attribute in collection. /// If found, comparing it's value with ignorable one. /// </summary> /// <param name="data">Object that contain member.</param> /// <param name="members">List of members that would be checked for this object.</param> /// <returns>Return member if value equal defined ignorable. /// Null if IsAutoIncrement not defined or object has not defaul value.</returns> public static MemberInfo GetIgnorable(ref object data, IEnumerable <MemberInfo> members) { #region Validate map // Detect columns (one in normal) with defined auto increment attribute. IEnumerable <MemberInfo> membersAutoInc = MembersHandler.FindMembersWithAttribute <IsAutoIncrementAttribute>(members); int count = membersAutoInc.Count(); if (count > 1) { string details = ""; foreach (MemberInfo mi in membersAutoInc) { details += "Name: " + mi.Name + " Type: " + mi.DeclaringType.Name + "\n"; } throw new NotSupportedException( "Allowed only one member with defined IsAutoIncrement attribute.\n" + " Cureently defined " + membersAutoInc.Count() + "\nList:\n" + details); } #endregion #region Detect if ignorable if (count > 0) { // Member that has undefined (ignorable) Auto increments value. MemberInfo memberInfo = membersAutoInc.First(); // if contains autoincrement columns. // Get auto increment settings descriptor. IsAutoIncrementAttribute iaiDescriptor = memberInfo.GetCustomAttribute <IsAutoIncrementAttribute>(); object memberValue = MembersHandler.GetValue(data, memberInfo); if (memberInfo is FieldInfo ? !IsIntLike(((FieldInfo)memberInfo).FieldType) : !IsIntLike(((PropertyInfo)memberInfo).PropertyType)) { throw new InvalidCastException("IsAutoIncrement attribute can be applied only to int-like types.\nAllowed types:\n" + "TypeCode.UInt16\n" + "TypeCode.UInt32\n" + "TypeCode.UInt64\n" + "TypeCode.Int16\n" + "TypeCode.Int32\n" + "TypeCode.Int64"); } else { return (memberValue.Equals(iaiDescriptor.ignoreValue) ? // If setted default value. memberInfo : // Return ignorable member. null); // Return null cause member must be included to comman. } } #endregion // Ignorable not found. return(null); }
/// <summary> /// Return unique index init string. /// </summary> /// <returns></returns> public string UniqueIndexDeclarationCommand(MemberInfo member) { // Looking for column attribute. if (!MembersHandler.TryToGetAttribute <ColumnAttribute>(member, out ColumnAttribute column)) { // Drop if not column. return(""); } return("UNIQUE INDEX `" + column.title + "_UNIQUE` (`" + column.title + "` ASC) VISIBLE"); }
/// <summary> /// Trying to set table if required. /// Not updating alter columns. /// </summary> /// <param name="disableSQLChecks">Disable check of data itegrity during command.</param> /// <param name="tableDescriptor">Type that would be trying to recreate on your SQL server. /// Must has defined UniformDataOperator.Sql.Attributes.Table attribute.</param> /// <param name="error">Error faces during operation.</param> /// <returns>Result of operation.</returns> public static bool TrySetTable(bool disableSQLChecks, Type tableDescriptor, out string error) { // Check is SQL operator exist. if (SqlOperatorHandler.Active == null) { throw new NullReferenceException("Active 'ISQLOperator' not exist. Select it before managing of database."); } // Drop if not table descriptor. if (!MembersHandler.HasAttribute <TableAttribute>(tableDescriptor)) { error = "Not defined Table attribute for target type."; return(false); } // Get command. string command; try { command = GenerateCreateTableCommand(tableDescriptor); } catch (Exception ex) { error = ex.Message; return(false); } #region Execute command // Tring to open connection to the server. if (!SqlOperatorHandler.Active.OpenConnection(out error)) { // Inform about fail. return(false); } // Disabling checks if requested. if (disableSQLChecks) { command = SqlOperatorHandler.Active.DisableSqlChecks(command); } // Execute command SqlOperatorHandler.Active.NewCommand(command)?.ExecuteNonQuery(); // Close connection after finish. SqlOperatorHandler.Active.CloseConnection(); // Confirm success. return(true); #endregion }
/// <summary> /// Looking for valid Table attribute. Chack all overridings and return correct descriptor. /// </summary> /// <param name="tableType">Type that contains defined Table attribute.</param> /// <param name="tableDescriptor">Output table descriptor.</param> /// <param name="error">Error message in cvase if occured. Null in other case.</param> /// <returns>A result of operation.</returns> public static bool TryToGetTableAttribute(Type tableType, out TableAttribute tableDescriptor, out string error) { // Drop if not table descriptor. if (!MembersHandler.TryToGetAttribute <TableAttribute>(tableType, out tableDescriptor)) { error = "Not defined Table attribute for target type."; tableDescriptor = null; return(false); } // Try to find overriding attribute for table descriptor. if (Modifiers.DBPathOverrideAttribute.TryToGetValidOverride <TableAttribute>( tableType, out Modifiers.DBPathOverrideAttribute tableOverrider)) { tableDescriptor.schema = tableOverrider.schema ?? tableDescriptor.schema; tableDescriptor.table = tableOverrider.table ?? tableDescriptor.table; } error = null; return(true); }
/// <summary> /// Adding members columns data to params. /// </summary> /// <param name="data">Object that contains values relative to members.</param> /// <param name="command">Command objects that would share values.</param> /// <param name="members">Members that with defined Column attribute that would be stored to command.</param> public static void MembersDataToCommand(ref object data, ref DbCommand command, IEnumerable <MemberInfo> members) { foreach (MemberInfo member in members) { // Get column. MembersHandler.TryToGetAttribute <ColumnAttribute>(member, out ColumnAttribute column); // Drop generated virtual columns. if (MembersHandler.TryToGetAttribute <IsGeneratedAttribute>(member, out IsGeneratedAttribute isGenerated) && isGenerated.mode == IsGeneratedAttribute.Mode.Virual) { continue; } // Add param. command.Parameters.Add( SqlOperatorHandler.Active.MemberToParameter( MembersHandler.GetValue(data, member), column) ); } }
/// <summary> /// Operating type to define if it must be registred in internal systems. /// </summary> /// <param name="type">Type that could contain defined `TypeReplacing` attribute.</param> public static void OperateType(Type type) { // Try to fine replacing instruction. if (!MembersHandler.TryToGetAttribute <TypeReplacer>(type, out TypeReplacer typeReplacer)) { // Drop cause type has no defined replacing attribute. return; } // Trying to find registred replacing meta. if (ExludingTable[typeReplacer.replacingType] is ReplacingMeta meta) { // Compare by priority. Operate if new instruction has highest priority. if (meta.replacedWithPriority < typeReplacer.overridingPriority) { // Update replacing data. meta.replacedWithPriority = typeReplacer.overridingPriority; meta.usingType = typeReplacer.usingType; Console.WriteLine("Type `{0}` replaced on `{1}`", typeReplacer.replacingType.FullName, typeReplacer.usingType.FullName); } return; } // Type instuction not registred. else { // Registrate new replacing isntruction. ExludingTable.Add( typeReplacer.replacingType, new ReplacingMeta() { usingType = typeReplacer.usingType, replacedWithPriority = typeReplacer.overridingPriority }); Console.WriteLine("Type `{0}` replaced on `{1}`", typeReplacer.replacingType.FullName, typeReplacer.usingType.FullName); } }
/// <summary> /// Return generated SQL command relative to init time. /// </summary> /// <param name="member">Member that contains defined attributes that describes column definition.</param> /// <returns>SQL command relative to MySql server.</returns> public string ColumnDeclarationCommand(MemberInfo member) { #region VALIDATION string command = ""; // Get column descriptor. if (!MembersHandler.TryToGetAttribute <ColumnAttribute>(member, out ColumnAttribute columnDescriptor)) { // Drop if not column. return(command); } #endregion #region TITLE // Set column title. command += "`" + columnDescriptor.title + "` "; #endregion #region TYPE // Detect specified overriding. if (MembersHandler.TryToGetAttribute(member, out Markup.MySqlDBTypeOverrideAttribute mySqlDBType)) { command += mySqlDBType.stringFormat ?? mySqlDBType.type.ToString(); } else { // Detect target type converted from common via param. command += SqlOperatorHandler.Active.DbTypeToString(columnDescriptor.type); } #endregion #region ZERO FILL if (MembersHandler.HasAttribute <IsZeroFillAttribute>(member)) { command += " ZEROFILL"; } #endregion #region BINARY if (MembersHandler.HasAttribute <IsBinaryAttribute>(member)) { command += " BINARY"; } #endregion #region UNASIGNED if (MembersHandler.HasAttribute <IsUnsignedAttribute>(member)) { command += " UNSIGNED"; } #endregion #region Generated | Default if (MembersHandler.TryToGetAttribute <DefaultAttribute>(member, out DefaultAttribute hasDefault) && !string.IsNullOrEmpty(hasDefault.defExp)) { // If generated if (hasDefault is IsGeneratedAttribute isGenerated) { command += " GENERATED ALWAYS AS("; command += isGenerated.defExp + ") "; command += (isGenerated.mode == IsGeneratedAttribute.Mode.Stored ? "STORED" : "VIRTUAL"); } // If has default. else { command += " DEFAULT " + hasDefault.defExp; } } #endregion #region NULL | NOT NULL // If not generated. if (hasDefault == null || !(hasDefault is IsGeneratedAttribute)) { if (MembersHandler.HasAttribute <IsPrimaryKeyAttribute>(member)) { command += " NOT NULL"; } else { // If has NotNull attribute. if (MembersHandler.HasAttribute <IsNotNullAttribute>(member)) { command += " NOT NULL"; } else { command += " NULL"; } } } #endregion #region AUTO INCREMENT // If has AutoIncrement attribute. if (MembersHandler.HasAttribute <IsAutoIncrementAttribute>(member)) { command += " AUTO_INCREMENT"; } #endregion #region COMMENT // Add commentary. if (MembersHandler.TryToGetAttribute <CommentaryAttribute>(member, out CommentaryAttribute commentary)) { command += " COMMENT '" + commentary + "'"; } #endregion return(command); }
/// <summary> /// Generating set to table sql command from provided source data. /// </summary> /// <param name="tableType">Type that has defined Table attribute. /// Would be used as table descriptor during queri building.</param> /// <param name="data">Object that contain's fields that would be writed to database. /// Affected only fields and properties with defined Column attribute.</param> /// <param name="error">Error faces during operation.</param> /// <returns>Generated command or null if failed.</returns> public DbCommand GenerateSetToTableCommand(Type tableType, object data, out string error) { #region Validate entry data // Check is SQL operator exist. if (Active == null) { throw new NullReferenceException("Active 'ISQLOperator' not exist. Select it before managing of database."); } // Loking for table descriptor. if (!TableAttribute.TryToGetTableAttribute(tableType, out TableAttribute tableDescriptor, out error)) { return(null); } #endregion #region Members detection // Detect memebers on objects that contain columns definition. List <MemberInfo> members = MembersHandler.FindMembersWithAttribute <ColumnAttribute>(data.GetType()).ToList(); // Drop set ignore columns. members = MembersHandler.FindMembersWithoutAttribute <SetQueryIgnoreAttribute>(members).ToList(); // Drop virtual generated columns. bool NotVirtual(MemberInfo member) { return(!(member.GetCustomAttribute <IsGeneratedAttribute>() is IsGeneratedAttribute isGenerated) || isGenerated.mode != IsGeneratedAttribute.Mode.Virual); }; members = MembersHandler.FindMembersWithoutAttribute <IsGeneratedAttribute>(members, NotVirtual).ToList(); // Trying to detect member with defined isAutoIncrement attribute that has default value. MemberInfo autoIncrementMember = null; try { autoIncrementMember = IsAutoIncrementAttribute.GetIgnorable(ref data, members); } catch (Exception ex) { error = ex.Message; return(null); } // Remove ignorable. if (autoIncrementMember != null) { members.Remove(autoIncrementMember); } // Find our not key elements. IEnumerable <MemberInfo> membersNK = MembersHandler.FindMembersWithoutAttribute <IsPrimaryKeyAttribute>(members); #endregion #region Generating command // Command that can be executed on the server. DbCommand command = Active.NewCommand(); // Set values as local params. ColumnAttribute.MembersDataToCommand(ref data, ref command, members); // Getting metas. ColumnAttribute.MembersToMetaLists(members, out List <ColumnAttribute> membersColumns, out List <string> membersVars); ColumnAttribute.MembersToMetaLists(membersNK, out List <ColumnAttribute> membersNKColumns, out List <string> membersNKVars); string commadText = ""; commadText += "INSERT INTO `" + tableDescriptor.schema + "`.`" + tableDescriptor.table + "`\n"; commadText += "\t\t(" + SqlOperatorHandler.CollectionToString(membersColumns) + ")\n"; commadText += "\tVALUES\n"; commadText += "\t\t(" + SqlOperatorHandler.CollectionToString(membersVars) + ")\n"; commadText += "\tON DUPLICATE KEY UPDATE\n"; commadText += "\t\t" + SqlOperatorHandler.ConcatFormatedCollections(membersNKColumns, membersNKVars, '\0') + ";\n"; command.CommandText = commadText; #endregion error = null; return(command); }
/// <summary> /// Return command that would allow to create table by descriptor. /// </summary> /// <param name="sourceType"></param> /// <returns></returns> public static string GenerateCreateTableCommand(Type sourceType) { // Loking for table descriptor. if (!TableAttribute.TryToGetTableAttribute(sourceType, out TableAttribute tableDescriptor, out string error)) { SqlOperatorHandler.InvokeSQLErrorOccured(sourceType, error); return(null); } // Variable that would contain SQL comand. string command = ""; command += "CREATE TABLE IF NOT EXISTS `" + tableDescriptor.schema + "`.`" + tableDescriptor.table + "` (\n"; IEnumerable <MemberInfo> columns = MembersHandler.FindMembersWithAttribute <ColumnAttribute>(sourceType); #region Declere columns string colCommand = ""; foreach (MemberInfo member in columns) { if (!string.IsNullOrEmpty(colCommand)) { colCommand += ",\n"; } colCommand += SqlOperatorHandler.Active.ColumnDeclarationCommand(member); } command += colCommand; #endregion #region Primary keys // Build PKs substring string. string subPkCommand = ""; foreach (MemberInfo cMeta in columns) { if (MembersHandler.TryToGetAttribute <IsPrimaryKeyAttribute>(cMeta, out IsPrimaryKeyAttribute isPrimaryKey)) { if (!string.IsNullOrEmpty(subPkCommand)) { subPkCommand += ", "; } MembersHandler.TryToGetAttribute <ColumnAttribute>(cMeta, out ColumnAttribute column); subPkCommand += "`" + column.title + "`"; } } // Add to command command if pks exist. command += subPkCommand.Length > 0 ? ",\nPRIMARY KEY(" + subPkCommand + ")" : ""; #endregion #region Unique indexes foreach (MemberInfo cMeta in columns) { if (MembersHandler.TryToGetAttribute <IsUniqueAttribute>(cMeta, out IsUniqueAttribute isUnique)) { command += ",\n"; command += isUnique.UniqueIndexDeclarationCommand(cMeta); } } #endregion #region FK indexes IsForeignKeyAttribute.DropIndexator(); foreach (MemberInfo cMeta in columns) { string decleration = IsForeignKeyAttribute.FKIndexDeclarationCommand(cMeta, tableDescriptor.table); if (!string.IsNullOrEmpty(decleration)) { command += ",\n" + decleration; } } #endregion #region Constraints IsForeignKeyAttribute.DropIndexator(); foreach (MemberInfo cMeta in columns) { string decleration = IsForeignKeyAttribute.ConstrainDeclarationCommand(cMeta, tableDescriptor.table); if (!string.IsNullOrEmpty(decleration)) { command += ",\n" + decleration; } } #endregion command += ")\n"; command += "ENGINE = " + (string.IsNullOrEmpty(tableDescriptor.engine) ? "InnoDB" : tableDescriptor.engine) + ";"; return(command); }
/// <summary> /// Insiniate UI by descriptor's attributes map and add it as child to parent element. /// </summary> /// <param name="root">UI element that would contain instiniated UI elemets.</param> public void BindTo(Panel root) { #region Getting descripting data // Getting relevant type. var selfType = this.GetType(); // Getting options applied to every memeber. var globalOptions = Attribute.GetCustomAttributes(selfType, typeof(Attribute)).Where (f => f.GetType().GetInterface(typeof(IGUILayoutOption).FullName) != null); // Get all memebers. var members = selfType.GetMembers(); // Sorting by order. var orderedMembers = members.Where(f => f.GetCustomAttribute <OrderAttribute>() != null). OrderBy(f => f.GetCustomAttribute <OrderAttribute>().Order); // Sorting disordered members by metadata. var disorderedMembers = members.Where(f => f.GetCustomAttribute <OrderAttribute>() == null). OrderBy(f => f.MetadataToken); #endregion // Sort in declaretion order. members = orderedMembers.Concat(disorderedMembers).ToArray(); // Instiniate first UILayer. activeLayer = new LayoutLayer() { root = root // Thet binding target as root for cuurent layer. }; // Perform all descriptor map. foreach (MemberInfo member in members) { #region Validation // Skip if the member is not field or property. if (!MembersHandler.GetSpecifiedMemberInfo( member, out PropertyInfo prop, out FieldInfo field)) { continue; } // Skip if member excluded from instpector. if (member.GetCustomAttribute <HideInInspectorAttribute>() != null) { continue; } #endregion // Getting all attributes. var attributes = member.GetCustomAttributes <Attribute>(true); // Allocating and defining types. var memberType = MembersHandler.GetSpecifiedMemberType(member); Type controlType = null; #region Perform general layout attributes // Perform general attributes. foreach (Attribute attr in attributes) { // Skip if an option. if (attr is IGUILayoutOption) { continue; } // Apply layout control to GUI. if (attr is IGUIElement attrControl) { attrControl.OnLayout(ref activeLayer, this, member); } } #endregion #region Defining UI field type // Check if default control was overrided by custom one. var customControlDesc = member.GetCustomAttribute <CustomControlAttribute>(); if (customControlDesc != null && // Is overriding requested? customControlDesc.ControlType != null && // Is target type is not null? customControlDesc.ControlType.IsSubclassOf(typeof(IGUIField))) // Is target type has correct inherience { // Set redefined control like target to instinitation. controlType = customControlDesc.ControlType; } else { // Set binded type like target to instiniation. controlType = LayoutHandler.GetBindedControl(memberType, true); } #endregion // Is control defined to that member? if (controlType != null) { #region Insiniation UI field // Instiniating target type. var control = (IGUIField)Activator.CreateInstance(controlType); // Sing up this control on desctiptor events. TryToBindControl(control, this, member); // Initialize control. control.OnLayout(ref activeLayer, this, member); // Adding field to the registration table. RegistredFields.Add(member, control); #endregion #region Set prefix label // Is spawned elelment has a label. if (control is UI.Controls.ILabel label) { // Instiniating handle that will provide managmend of the control. ContentAttribute localizationHandler = null; // Try to get described one. if (UniformDataOperator.AttributesHandler. TryToGetAttribute(member, out ContentAttribute attribute)) { // Buferize if found. localizationHandler = attribute; } else { // Initialize new one. localizationHandler = ContentAttribute.Empty; } // Binding spawned element to the conent. localizationHandler.BindToLable(label, member); } #endregion #region Perform Layout options // Check if spawned control is framework element. if (control is FrameworkElement fEl) { // Applying global options foreach (IGUILayoutOption option in globalOptions) { option.ApplyLayoutOption(fEl); } // Perform options attributes. foreach (Attribute attr in attributes) { // Skip if not an option. if (!(attr is IGUILayoutOption option)) { continue; } // Applying option to the element. option.ApplyLayoutOption(fEl); } } #endregion } else { // Check if that just other descriptor. if (memberType.IsSubclassOf(typeof(UIDescriptor))) { #region Configurating layout // Add horizontal shift for sub descriptor. new BeginHorizontalGroupAttribute().OnLayout(ref activeLayer); new Controls.SpaceAttribute(10).OnLayout(ref activeLayer); // Add vertical group. var vertGroup = new BeginVerticalGroupAttribute(); vertGroup.OnLayout(ref activeLayer); #endregion #region Looking for descriptor object. // Bufer that will contain value of the descriptor. UIDescriptor subDesc = null; // Trying to get value via reflection. subDesc = prop != null? prop.GetValue(this) as UIDescriptor: // Operate like property. field.GetValue(this) as UIDescriptor; // Operate like fields. // Instiniate default in case if value is null. if (subDesc == null) { try { // Insiniate empty constructor. subDesc = Activator.CreateInstance(memberType) as UIDescriptor; } catch (Exception ex) { // Log error. MessageBox.Show("UIDescriptor must contain empty constructor, " + "or be instiniated before calling into UI." + "\n\nDetails:\n" + ex.Message); // Skip to the next member. continue; } // Updating stored value for current member. if (prop != null) { prop.SetValue(this, subDesc); } else { field.SetValue(this, subDesc); } } #endregion // Binding descriptor to the UI. subDesc.BindTo((Panel)activeLayer.root); } } } // Marking as loaded. IsLoaded = true; // Inform subscribers. Loaded?.Invoke(this); }
/// <summary> /// Unbinding descriptor from panel. /// Will affect only memeber defied into descriptor and leave and other GUI elements childed to the panel. /// </summary> /// <param name="root">Root panle that was binding target for descriptor.</param> public void UnbindFrom(Panel root) { // Get all memebers. var members = GetType().GetMembers(); // Checking every child into the root. for (int i = 0; i < root.Children.Count; i++) { // Getting current child. var child = root.Children[i]; // If child is layout control and has a binded memeber. if (child is IGUIField control && control.BindedMember != null) { #region Validation // Checking is the binded memeber is a part of the descriptor. bool thisDesc = false; foreach (var member in members) { // Check if binded member is the one from the descriptor. if (member.Equals(control.BindedMember)) { thisDesc = true; break; } } // Skip if not possesed to that descriptor. if (!thisDesc) { continue; } #endregion #region Unbind control from UI // Unsubscribe element from hadler's events. LayoutHandler.UnregistrateField(control); // Remove from UI. root.Children.RemoveAt(i); i--; #endregion #region Sub descriptor processing // If member is UI descriptor. if (control is Panel subPanel && MembersHandler.GetSpecifiedMemberType(control.BindedMember).IsSubclassOf(typeof(UIDescriptor))) { try { // Requiest descriptor unbinding. ((UIDescriptor)control.Value).UnbindFrom(subPanel); } catch (Exception ex) { // Log error. MessageBox.Show("Subpanel UIDescriptor unbind operation failed." + "\n\nDetails:\n" + ex.Message); } } #endregion } } }
/// <summary> /// Trying to find member with defined IsAutoIncrement attribute in collection. /// If found, comparing it's value with ignorable one. /// /// Scaning all members that has defined Column attribute. /// </summary> /// <param name="data">Object that contain member.</param> /// <returns>Return member if value equal defined ignorable. /// Null if IsAutoIncrement not defined or object has not defaul value.</returns> public static MemberInfo GetIgnorable(ref object data) { return(GetIgnorable(ref data, MembersHandler.FindMembersWithAttribute <ColumnAttribute>(data.GetType()))); }