Added DbForeignObject for automatic resolving
Added Init() to initialise necessary classes Changed structure and added a BaseAttribute Fixed occuring errors to match new system
This commit is contained in:
		
							parent
							
								
									9253d77236
								
							
						
					
					
						commit
						85495af97f
					
				
							
								
								
									
										20
									
								
								Database-Attribute_System/Attributes/BaseAttribute.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								Database-Attribute_System/Attributes/BaseAttribute.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Reflection;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace eu.railduction.netcore.dll.Database_Attribute_System.Attributes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class BaseAttribute : Attribute
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public FieldInfo parentField;
 | 
				
			||||||
 | 
					        public DbObject classAttribute;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string _attributeName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public BaseAttribute()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,22 +1,29 @@
 | 
				
			|||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Reflection;
 | 
				
			||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace eu.railduction.netcore.dll.Database_Attribute_System.Attributes
 | 
					namespace eu.railduction.netcore.dll.Database_Attribute_System.Attributes
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
 | 
					    [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
 | 
				
			||||||
    public class DbAttribute : Attribute
 | 
					    public class DbAttribute : BaseAttribute
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public string _attributeName;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Marks variable as database-attribute
 | 
					        /// Marks variable as database-attribute
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="dbAttributeName">Name of database-attribute (case-sensitivity is determined from database-attribute-settings) ['null' if the same as field-name]</param>
 | 
					        /// <param name="dbAttributeName">Name of database-attribute (case-sensitivity is determined from database-attribute-settings) ['null' if the same as field-name]</param>
 | 
				
			||||||
        public DbAttribute(string attributeName = null)
 | 
					        public DbAttribute(string attributeName = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            this._attributeName = attributeName;    // Todo: Automatic resolving of name if it is null (?)
 | 
					            this._attributeName = attributeName;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Init(FieldInfo fi, DbObject classAttribute)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this.parentField = fi;
 | 
				
			||||||
 | 
					            this.classAttribute = classAttribute;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this._attributeName = this._attributeName ?? fi.Name;     // If no alternative attribute-name is specified, use the property-name
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Reflection;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace eu.railduction.netcore.dll.Database_Attribute_System.Attributes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
 | 
				
			||||||
 | 
					    public class DbForeignKey : BaseAttribute
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Marks variable as foreignKey of given class
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="dbAttributeName">Name of database-attribute (case-sensitivity is determined from database-attribute-settings) ['null' if the same as field-name]</param>
 | 
				
			||||||
 | 
					        public DbForeignKey(string attributeName = null)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this._attributeName = attributeName;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Init(FieldInfo fi, DbObject classAttribute)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this.parentField = fi;
 | 
				
			||||||
 | 
					            this.classAttribute = classAttribute;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this._attributeName = this._attributeName ?? fi.Name;     // If no alternative attribute-name is specified, use the property-name
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,16 +1,14 @@
 | 
				
			|||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Reflection;
 | 
				
			||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace eu.railduction.netcore.dll.Database_Attribute_System.Attributes
 | 
					namespace eu.railduction.netcore.dll.Database_Attribute_System.Attributes
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
 | 
					    [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
 | 
				
			||||||
    public class DbPrimaryKey : Attribute
 | 
					    public class DbPrimaryKey : BaseAttribute
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public Type _classType;
 | 
					 | 
				
			||||||
        public string _attributeName;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Marks variable as primaryKey fo current class
 | 
					        /// Marks variable as primaryKey fo current class
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
@ -19,5 +17,13 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System.Attributes
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            this._attributeName = attributeName;    // Todo: Automatic resolving of name if it is null (?)
 | 
					            this._attributeName = attributeName;    // Todo: Automatic resolving of name if it is null (?)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Init(FieldInfo fi, DbObject classAttribute)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this.parentField = fi;
 | 
				
			||||||
 | 
					            this.classAttribute = classAttribute;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this._attributeName = this._attributeName ?? fi.Name;     // If no alternative attribute-name is specified, use the property-name
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1,43 +0,0 @@
 | 
				
			|||||||
using System;
 | 
					 | 
				
			||||||
using System.Collections.Generic;
 | 
					 | 
				
			||||||
using System.Linq;
 | 
					 | 
				
			||||||
using System.Reflection;
 | 
					 | 
				
			||||||
using System.Threading.Tasks;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace eu.railduction.netcore.dll.Database_Attribute_System.Attributes
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
 | 
					 | 
				
			||||||
    public class DbForeignKey : Attribute
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public Type _classType;
 | 
					 | 
				
			||||||
        public string _attributeName;
 | 
					 | 
				
			||||||
        public string _foreignKeyFieldName;
 | 
					 | 
				
			||||||
        public FieldInfo _foreignKeyField;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Marks variable as foreignKey of given class
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <param name="classType">Type of class to which this is the ForeignKey</param>
 | 
					 | 
				
			||||||
        /// <param name="dbAttributeName">Name of database-attribute (case-sensitivity is determined from database-attribute-settings) ['null' if the same as field-name]</param>
 | 
					 | 
				
			||||||
        /// <param name="foreignKeyFieldName">Name of foreignKey-fieldName ['null' if the same as classType-name]</param>
 | 
					 | 
				
			||||||
        public DbForeignKey(Type classType, string foreignKeyFieldName = null, string attributeName = null)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            this._classType = classType;
 | 
					 | 
				
			||||||
            this._attributeName = attributeName;    // Todo: Automatic resolving of name if it is null (?)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            bool fieldFound = false;
 | 
					 | 
				
			||||||
            foreach (System.Reflection.FieldInfo fi in classType.GetRuntimeFields())
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if(fi.Name.ToLower() == foreignKeyFieldName.ToLower())
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    this._foreignKeyFieldName = fi.Name;
 | 
					 | 
				
			||||||
                    this._foreignKeyField = fi;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    fieldFound = true;
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (!fieldFound) throw new InvalidOperationException($"Field with name='{foreignKeyFieldName}' not found in {classType.Name}.");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										80
									
								
								Database-Attribute_System/Attributes/DbForeignObject.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								Database-Attribute_System/Attributes/DbForeignObject.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,80 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Reflection;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace eu.railduction.netcore.dll.Database_Attribute_System.Attributes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
 | 
				
			||||||
 | 
					    public class DbForeignObject : Attribute
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public Type _foreignObjectType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string _foreignKeyName;
 | 
				
			||||||
 | 
					        public DbForeignKey foreignKeyAttribute;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public FieldInfo parentField;
 | 
				
			||||||
 | 
					        public DbObject classAttribute;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Marks variable as foreign-object of an dbObject
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="foreignObjectType">Type of foreignObject</param>
 | 
				
			||||||
 | 
					        /// <param name="foreignKeyName">Fieldname of foreignKey associated with the foreignObject</param>
 | 
				
			||||||
 | 
					        public DbForeignObject(Type foreignObjectType, string foreignKeyName = null)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this._foreignObjectType = foreignObjectType;
 | 
				
			||||||
 | 
					            this._foreignKeyName = foreignKeyName;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Init(FieldInfo fi, DbObject classAttribute)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this.parentField = fi;
 | 
				
			||||||
 | 
					            this.classAttribute = classAttribute;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Init foreign-object class
 | 
				
			||||||
 | 
					            DbObject foreignClassAttribute = ClassAction.Init(this._foreignObjectType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Check if something is weird
 | 
				
			||||||
 | 
					            if (foreignClassAttribute.primaryKeyAttributes.Count < 1) throw new InvalidOperationException($"'{foreignClassAttribute.parentClassType.Name}' does not have a primaryKey.");
 | 
				
			||||||
 | 
					            if (foreignClassAttribute.primaryKeyAttributes.Count > 1) throw new InvalidOperationException($"ForeignObject does not support multiple primaryKeys.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Type primaryKeyType = foreignClassAttribute.primaryKeyAttributes[0].parentField.GetType();  // Read type of primaryKey in foreignObject-class
 | 
				
			||||||
 | 
					            foreach(DbForeignKey foreignKey in classAttribute.foreignKeyAttributes)     // Search for matching foreignKey
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if(this._foreignKeyName != null)     // If i have a name
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // check if name matches
 | 
				
			||||||
 | 
					                    if (foreignKey.parentField.Name.ToLower() == this._foreignKeyName)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        if(foreignKey.parentField.GetType() == primaryKeyType)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            this._foreignKeyName = foreignKey.parentField.Name;
 | 
				
			||||||
 | 
					                            foreignKeyAttribute = foreignKey;
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        else
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            // If a name was specified and the key does not match its an error
 | 
				
			||||||
 | 
					                            throw new InvalidOperationException($"ForeignKey='{this._foreignKeyName}' is typeOf='{foreignKey.parentField.GetType().Name}' but primaryKey of foreignObject-class is typeOf='{primaryKeyType.Name}'.");
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else    // No name
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // Check if type matches
 | 
				
			||||||
 | 
					                    if (foreignKey.parentField.GetType() == primaryKeyType)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        this._foreignKeyName = foreignKey.parentField.Name;
 | 
				
			||||||
 | 
					                        foreignKeyAttribute = foreignKey;
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Check if key-retrieval was successful
 | 
				
			||||||
 | 
					            if (foreignKeyAttribute == null) throw new InvalidOperationException($"No coresponding foreignKey.");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -12,6 +12,15 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System.Attributes
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        public string _tableName;
 | 
					        public string _tableName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Type parentClassType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // All childrenAttributes
 | 
				
			||||||
 | 
					        public List<BaseAttribute> baseAttributes = new List<BaseAttribute>() { };
 | 
				
			||||||
 | 
					        public List<DbPrimaryKey> primaryKeyAttributes = new List<DbPrimaryKey>() { };
 | 
				
			||||||
 | 
					        public List<DbAttribute> attributeAttributes = new List<DbAttribute>() { };
 | 
				
			||||||
 | 
					        public List<DbForeignKey> foreignKeyAttributes = new List<DbForeignKey>() { };
 | 
				
			||||||
 | 
					        public List<DbForeignObject> foreignObjectAttributes = new List<DbForeignObject>() { };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Marks variable as database-table
 | 
					        /// Marks variable as database-table
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
@ -20,5 +29,51 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System.Attributes
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            this._tableName = tableName;    // Todo: Automatic resolving of name if it is null (?)
 | 
					            this._tableName = tableName;    // Todo: Automatic resolving of name if it is null (?)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Init(Type classType)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this.parentClassType = classType;
 | 
				
			||||||
 | 
					            this._tableName = this._tableName ?? classType.Name;    // If no alternative table-name is specified, use the class-name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Iterate thru all fields
 | 
				
			||||||
 | 
					            foreach (System.Reflection.FieldInfo fi in classType.GetRuntimeFields())
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                try
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // Check if current field is a db-field and initiate it
 | 
				
			||||||
 | 
					                    if (fi.GetCustomAttribute(typeof(DbPrimaryKey), true) is DbPrimaryKey pkey)     // PrimaryKey
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        pkey.Init(fi, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        this.baseAttributes.Add(pkey);
 | 
				
			||||||
 | 
					                        this.primaryKeyAttributes.Add(pkey);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else if (fi.GetCustomAttribute(typeof(DbAttribute), true) is DbAttribute att)   // Attributes
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        att.Init(fi, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        this.baseAttributes.Add(att);
 | 
				
			||||||
 | 
					                        this.attributeAttributes.Add(att);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else if (fi.GetCustomAttribute(typeof(DbForeignKey), true) is DbForeignKey fkey)    // ForeignKeys
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        fkey.Init(fi, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        this.baseAttributes.Add(fkey);
 | 
				
			||||||
 | 
					                        this.foreignKeyAttributes.Add(fkey);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else if (fi.GetCustomAttribute(typeof(DbForeignObject), true) is DbForeignObject fobj)    // ForeignObjects
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        fobj.Init(fi, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        this.foreignObjectAttributes.Add(fobj);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                catch(InvalidOperationException ex)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    throw new InvalidOperationException($"Cannot init foreignObject-field '{fi.Name}' of '{classType.Name}'. {ex.Message}", ex);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,29 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    public class ClassAction
 | 
					    public class ClassAction
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        private static List<Type> initiatedClassTypes = new List<Type>() { };
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Initiates the attribute-system and preloads all necessary information<para/>
 | 
				
			||||||
 | 
					        /// INFO: Will initiate necessary foreignObjects recursively!<para/>
 | 
				
			||||||
 | 
					        /// If an class is already initiated, it will be ignored!
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="classType">The classType to preload</param>
 | 
				
			||||||
 | 
					        /// <returns>DbObject-attribute corresponding to the class</returns>
 | 
				
			||||||
 | 
					        public static DbObject Init(Type classType)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Check if given class is marked as dbObject
 | 
				
			||||||
 | 
					            if (!(classType.GetCustomAttribute(typeof(DbObject), true) is DbObject dbObject)) throw new InvalidOperationException($"Cannot init '{classType.Name}'. Missing Attribute 'DbObject'");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!initiatedClassTypes.Contains(classType))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                dbObject.Init(classType);   // Init dbObject
 | 
				
			||||||
 | 
					                initiatedClassTypes.Add(classType);     // Set it to the list
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return dbObject;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Fills an given dbObject with given data<para/>
 | 
					        /// Fills an given dbObject with given data<para/>
 | 
				
			||||||
        /// Data-attribute-names and class-fieldNames have to match! (non case-sensitive)
 | 
					        /// Data-attribute-names and class-fieldNames have to match! (non case-sensitive)
 | 
				
			||||||
@ -16,55 +39,23 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System
 | 
				
			|||||||
        /// <param name="classObject">Given object (marked with Db-attributes)</param>
 | 
					        /// <param name="classObject">Given object (marked with Db-attributes)</param>
 | 
				
			||||||
        /// <param name="data">The data</param>
 | 
					        /// <param name="data">The data</param>
 | 
				
			||||||
        /// <param name="runDataLossChecks">This checks if any class-field and data-attribute does not exists in either (Slower)</param>
 | 
					        /// <param name="runDataLossChecks">This checks if any class-field and data-attribute does not exists in either (Slower)</param>
 | 
				
			||||||
        public static void FillObject<T>(T classObject, Dictionary<string, object> data, bool runDataLossChecks = true)
 | 
					        public static void FillObject<T>(T classObject, Dictionary<string, object> data)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Type classType = classObject.GetType();
 | 
					            Type classType = classObject.GetType();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            string tableName = Function.GetDbTableName(classType);
 | 
					            // Read dbObject-attribute
 | 
				
			||||||
 | 
					            DbObject dbObject = ClassAction.Init(classType);
 | 
				
			||||||
            // Get class-fields
 | 
					 | 
				
			||||||
            Dictionary<string, FieldInfo> dbFields = Function.ReadDbClassFields(classType);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (runDataLossChecks)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                // Check every data-attribute for match in class-fields
 | 
					 | 
				
			||||||
                foreach (KeyValuePair<string, object> data_keySet in data)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    bool isFound = false;
 | 
					 | 
				
			||||||
                    foreach (KeyValuePair<string, FieldInfo> field_keySet in dbFields)
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        if (field_keySet.Key.ToLower() == data_keySet.Key.ToLower())
 | 
					 | 
				
			||||||
                            isFound = true;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (!isFound)
 | 
					 | 
				
			||||||
                        throw new InvalidOperationException($"Could not fill object. Data-Attribute '{data_keySet.Key}' was not found in class!");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                // Check every class-field for match in data-attributes
 | 
					 | 
				
			||||||
                foreach (KeyValuePair<string, FieldInfo> field_keySet in dbFields)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    bool isFound = false;
 | 
					 | 
				
			||||||
                    foreach (KeyValuePair<string, object> data_keySet in data)
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        if (field_keySet.Key.ToLower() == data_keySet.Key.ToLower())
 | 
					 | 
				
			||||||
                            isFound = true;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (!isFound)
 | 
					 | 
				
			||||||
                        throw new InvalidOperationException($"Could not fill object. Class-field '{field_keySet.Key}' was not found in data!");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }      
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Iterate through data
 | 
					            // Iterate through data
 | 
				
			||||||
            foreach (KeyValuePair<string, object> data_keySet in data)
 | 
					            foreach (KeyValuePair<string, object> data_keySet in data)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // Interate through class-fields
 | 
					                // Interate through class-fields
 | 
				
			||||||
                foreach (KeyValuePair<string, FieldInfo> field_keySet in dbFields)
 | 
					                foreach (BaseAttribute baseAttribute in dbObject.baseAttributes)
 | 
				
			||||||
                { 
 | 
					                { 
 | 
				
			||||||
                    // If its a match, set the value
 | 
					                    // If its a match, set the value
 | 
				
			||||||
                    if (field_keySet.Key.ToLower() == data_keySet.Key.ToLower())
 | 
					                    if (baseAttribute._attributeName.ToLower() == data_keySet.Key.ToLower())
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        field_keySet.Value.SetValue(classObject, data_keySet.Value);
 | 
					                        baseAttribute.parentField.SetValue(classObject, data_keySet.Value);
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@ -79,57 +70,54 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System
 | 
				
			|||||||
        /// <param name="classObject">Given object (marked with Db-attributes)</param>
 | 
					        /// <param name="classObject">Given object (marked with Db-attributes)</param>
 | 
				
			||||||
        /// <param name="queryExecutor">Function to handle query-calls - Has to return Dictionary[attributeName, attributeValue]</param>
 | 
					        /// <param name="queryExecutor">Function to handle query-calls - Has to return Dictionary[attributeName, attributeValue]</param>
 | 
				
			||||||
        /// <param name="runDataLossChecks">This checks if any class-field and data-attribute does not exists in either (Slower)</param>
 | 
					        /// <param name="runDataLossChecks">This checks if any class-field and data-attribute does not exists in either (Slower)</param>
 | 
				
			||||||
        public static T GetByPrimaryKey<T>(Type classType, object primaryKeyValue, Func<string, List<Dictionary<string, object>>> queryExecutor, bool runDataLossChecks = true) where T : new()
 | 
					        public static T GetByPrimaryKey<T>(Type classType, object primaryKeyValue, Func<string, List<Dictionary<string, object>>> queryExecutor) where T : new()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Dictionary<string, object> primaryKeyData = new Dictionary<string, object>() { };
 | 
					            Dictionary<string, object> primaryKeyData = new Dictionary<string, object>() { };
 | 
				
			||||||
            primaryKeyData.Add(null, primaryKeyValue);
 | 
					            primaryKeyData.Add(null, primaryKeyValue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return GetByPrimaryKey<T>(classType, primaryKeyData, queryExecutor, runDataLossChecks);
 | 
					            return GetByPrimaryKey<T>(classType, primaryKeyData, queryExecutor);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        public static T GetByPrimaryKey<T>(Type classType, string primaryKeyName, object primaryKeyValue, Func<string, List<Dictionary<string, object>>> queryExecutor, bool runDataLossChecks = true) where T : new()
 | 
					        public static T GetByPrimaryKey<T>(Type classType, string primaryKeyName, object primaryKeyValue, Func<string, List<Dictionary<string, object>>> queryExecutor) where T : new()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Dictionary<string, object> primaryKeyData = new Dictionary<string, object>() { };
 | 
					            Dictionary<string, object> primaryKeyData = new Dictionary<string, object>() { };
 | 
				
			||||||
            primaryKeyData.Add(primaryKeyName, primaryKeyValue);
 | 
					            primaryKeyData.Add(primaryKeyName, primaryKeyValue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return GetByPrimaryKey<T>(classType, primaryKeyData, queryExecutor, runDataLossChecks);
 | 
					            return GetByPrimaryKey<T>(classType, primaryKeyData, queryExecutor);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        public static T GetByPrimaryKey<T>(Type classType, Dictionary<string, object> primaryKeyData, Func<string, List<Dictionary<string, object>>> queryExecutor, bool runDataLossChecks = true) where T: new()
 | 
					        public static T GetByPrimaryKey<T>(Type classType, Dictionary<string, object> primaryKeyData, Func<string, List<Dictionary<string, object>>> queryExecutor) where T: new()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // Create new empty object
 | 
					            // Create new empty object
 | 
				
			||||||
            T obj = new T();
 | 
					            T obj = new T();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Read all fields
 | 
					            // Read dbObject-attribute
 | 
				
			||||||
            Dictionary<string, FieldInfo> dbFields = Function.ReadDbClassFields(classType);
 | 
					            DbObject dbObject = ClassAction.Init(classType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // iterate thru them to check and fill object
 | 
					            // iterate thru them to check and fill object
 | 
				
			||||||
            foreach (KeyValuePair<string, FieldInfo> field in dbFields)
 | 
					            foreach (DbPrimaryKey primaryKeyAtt in dbObject.primaryKeyAttributes)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // primaryKeys
 | 
					                bool dataMatchFound = false;
 | 
				
			||||||
                if (field.Value.GetCustomAttribute(typeof(DbPrimaryKey), true) is DbPrimaryKey pkey)
 | 
					
 | 
				
			||||||
 | 
					                // Now search the corresponding primaryKeyData
 | 
				
			||||||
 | 
					                foreach (KeyValuePair<string, object> primaryKey in primaryKeyData)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    bool dataMatchFound = false;
 | 
					                    // primaryKey matches
 | 
				
			||||||
 | 
					                    if(primaryKeyAtt._attributeName.ToLower() == primaryKey.Key.ToLower())
 | 
				
			||||||
                    // Now search the corresponding primaryKeyData
 | 
					 | 
				
			||||||
                    foreach (KeyValuePair<string, object> primaryKey in primaryKeyData)
 | 
					 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        // primaryKey matches
 | 
					                        // Set data
 | 
				
			||||||
                        if(field.Value.Name.ToLower() == primaryKey.Key.ToLower())
 | 
					                        primaryKeyAtt.parentField.SetValue(obj, primaryKey.Value);
 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            // Set data
 | 
					 | 
				
			||||||
                            field.Value.SetValue(obj, primaryKey.Value);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            dataMatchFound = true;
 | 
					                        dataMatchFound = true;
 | 
				
			||||||
                            break;
 | 
					                        break;
 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
                    // If no data was found matching this field
 | 
					 | 
				
			||||||
                    if (!dataMatchFound) throw new InvalidOperationException($"Cannot create object with primaryKeyData. No data assigned to field '{field.Value.Name}'");
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // If no data was found matching this field
 | 
				
			||||||
 | 
					                if (!dataMatchFound) throw new InvalidOperationException($"Cannot create object with primaryKeyData. No data assigned to field '{primaryKeyAtt.parentField.Name}'");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            string query = QueryBuilder.SelectByPrimaryKey(obj);   // Generate query
 | 
					            string query = QueryBuilder.SelectByPrimaryKey(obj);   // Generate query
 | 
				
			||||||
            List<Dictionary<string, object>> dataSet = queryExecutor(query);    // Execute
 | 
					            List<Dictionary<string, object>> dataSet = queryExecutor(query);    // Execute
 | 
				
			||||||
            FillObject(obj, dataSet[0], runDataLossChecks);   // Fill the object
 | 
					            FillObject(obj, dataSet[0]);   // Fill the object
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return obj;
 | 
					            return obj;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -142,21 +130,22 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System
 | 
				
			|||||||
        /// <param name="fields">class-fields for select</param>
 | 
					        /// <param name="fields">class-fields for select</param>
 | 
				
			||||||
        /// <param name="queryExecutor">Function to handle query-calls - Has to return Dictionary[attributeName, attributeValue]</param>
 | 
					        /// <param name="queryExecutor">Function to handle query-calls - Has to return Dictionary[attributeName, attributeValue]</param>
 | 
				
			||||||
        /// <param name="runDataLossChecks">This checks if any class-field and data-attribute does not exists in either (Slower)</param>
 | 
					        /// <param name="runDataLossChecks">This checks if any class-field and data-attribute does not exists in either (Slower)</param>
 | 
				
			||||||
        /// <returns></returns>
 | 
					        /// <returns>List of dbObjects</returns>
 | 
				
			||||||
        public static List<T> GetListByAttribute<T>(Type classType, Dictionary<string, object> fields, Func<string, List<Dictionary<string, object>>> queryExecutor, bool runDataLossChecks = true) where T : new()
 | 
					        public static List<T> GetListByAttribute<T>(Type classType, Dictionary<string, object> fields, Func<string, List<Dictionary<string, object>>> queryExecutor) where T : new()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            string tableName = Function.GetDbTableName(classType);  // Get database-tableName
 | 
					            // Read dbObject-attribute
 | 
				
			||||||
 | 
					            DbObject dbObject = ClassAction.Init(classType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Function.ConvertAttributeToDbAttributes(classType, fields);
 | 
					            Function.ConvertAttributeToDbAttributes(classType, fields);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            string query = QueryBuilder.SelectByAttribute(tableName, fields);   // Generate query
 | 
					            string query = QueryBuilder.SelectByAttribute(dbObject._tableName, fields);   // Generate query
 | 
				
			||||||
            List<Dictionary<string, object>> dataSet = queryExecutor(query);    // Execute
 | 
					            List<Dictionary<string, object>> dataSet = queryExecutor(query);    // Execute
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            List<T> objs = new List<T>() { };
 | 
					            List<T> objs = new List<T>() { };
 | 
				
			||||||
            foreach(Dictionary<string, object> data in dataSet)
 | 
					            foreach(Dictionary<string, object> data in dataSet)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                T obj = new T();    // New object
 | 
					                T obj = new T();    // New object
 | 
				
			||||||
                FillObject(obj, data, runDataLossChecks);   // Fill it
 | 
					                FillObject(obj, data);   // Fill it
 | 
				
			||||||
                objs.Add(obj);      // Add to list
 | 
					                objs.Add(obj);      // Add to list
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -174,32 +163,27 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System
 | 
				
			|||||||
        /// <param name="queryExecutor">Function to handle query-calls - Has to return Dictionary[attributeName, attributeValue]</param>
 | 
					        /// <param name="queryExecutor">Function to handle query-calls - Has to return Dictionary[attributeName, attributeValue]</param>
 | 
				
			||||||
        /// <param name="max_depth">Determents how deep resolving will be executed</param>
 | 
					        /// <param name="max_depth">Determents how deep resolving will be executed</param>
 | 
				
			||||||
        /// <param name="runDataLossChecks">This checks if any class-field and data-attribute does not exists in either (Slower)</param>
 | 
					        /// <param name="runDataLossChecks">This checks if any class-field and data-attribute does not exists in either (Slower)</param>
 | 
				
			||||||
        public static void ResolveForeignKeys<T>(T classObject, Func<string, List<Dictionary<string, object>>> queryExecutor, int max_depth = 1, bool runDataLossChecks = true) where T: new()
 | 
					        public static void ResolveForeignKeys<T>(T classObject, Func<string, List<Dictionary<string, object>>> queryExecutor, int max_depth = 1) where T: new()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Type classType = classObject.GetType();
 | 
					            Type classType = classObject.GetType();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Get class-fields
 | 
					            // Read dbObject-attribute
 | 
				
			||||||
            Dictionary<string, FieldInfo> dbFields = Function.ReadDbClassFields(classType);
 | 
					            DbObject dbObject = ClassAction.Init(classType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (KeyValuePair<string, FieldInfo> dbField in dbFields)
 | 
					            foreach (DbForeignObject foreignObjectAtt in dbObject.foreignObjectAttributes)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // If field is foreignKey
 | 
					                object foreignObject_value = foreignObjectAtt.parentField.GetValue(classObject);
 | 
				
			||||||
                if (dbField.Value.GetCustomAttribute(typeof(DbForeignKey), true) is DbForeignKey fkey)
 | 
					
 | 
				
			||||||
 | 
					                // When its empty, get it
 | 
				
			||||||
 | 
					                if(foreignObject_value == null)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    FieldInfo f_Field = fkey._foreignKeyField;
 | 
					                    foreignObject_value = GetByPrimaryKey<T>(classType, foreignObjectAtt.foreignKeyAttribute.parentField.GetValue(classObject), queryExecutor); ;
 | 
				
			||||||
                    object f_value = f_Field.GetValue(classObject);
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    // When its empty, get it
 | 
					                // Recursive resolving
 | 
				
			||||||
                    if(f_value == null)
 | 
					                if (max_depth - 1 > 0)
 | 
				
			||||||
                    {
 | 
					                {
 | 
				
			||||||
                        f_value = GetByPrimaryKey<T>(classType, f_value, queryExecutor, runDataLossChecks); ;
 | 
					                    ResolveForeignKeys(foreignObject_value, queryExecutor, max_depth - 1);
 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    // Recursive resolving
 | 
					 | 
				
			||||||
                    if (max_depth - 1 > 0)
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        ResolveForeignKeys(f_value, queryExecutor, max_depth - 1, runDataLossChecks);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@
 | 
				
			|||||||
    <TargetFramework>netcoreapp2.1</TargetFramework>
 | 
					    <TargetFramework>netcoreapp2.1</TargetFramework>
 | 
				
			||||||
    <RootNamespace>eu.railduction.netcore.dll.Database_Attribute_System</RootNamespace>
 | 
					    <RootNamespace>eu.railduction.netcore.dll.Database_Attribute_System</RootNamespace>
 | 
				
			||||||
    <SignAssembly>false</SignAssembly>
 | 
					    <SignAssembly>false</SignAssembly>
 | 
				
			||||||
    <Version>1.4.1</Version>
 | 
					    <Version>1.5</Version>
 | 
				
			||||||
  </PropertyGroup>
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</Project>
 | 
					</Project>
 | 
				
			||||||
 | 
				
			|||||||
@ -18,17 +18,14 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            Type classType = classObject.GetType();
 | 
					            Type classType = classObject.GetType();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Get db-table-name from class
 | 
					            // Read dbObject-attribute
 | 
				
			||||||
            string tableName = Function.GetDbTableName(classType);
 | 
					            DbObject dbObject = ClassAction.Init(classType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Get class db-fields
 | 
					            // Check if 'byPrimaryKey' is possible
 | 
				
			||||||
            Dictionary<string, object> dbPrimaryKeys = new Dictionary<string, object>() { };
 | 
					            if (dbObject.primaryKeyAttributes.Count == 0) throw new InvalidOperationException($"Cannot generate SQL-Query of '{classType.Name}'. No primary-key/s!");
 | 
				
			||||||
            Dictionary<string, object> dbAttributes = new Dictionary<string, object>() { };
 | 
					            Dictionary<string, object> dbPrimaryKeys = Function.ReadFieldData(Function.ConvertToDerivedList(dbObject.primaryKeyAttributes), classObject);
 | 
				
			||||||
            Dictionary<string, object> dbForeignKeys = new Dictionary<string, object>() { };
 | 
					 | 
				
			||||||
            Function.ReadDbClassFields(classObject, ref dbPrimaryKeys, ref dbAttributes, ref dbForeignKeys);
 | 
					 | 
				
			||||||
            if (dbPrimaryKeys.Count == 0) throw new InvalidOperationException($"Cannot generate SQL-Query of '{classType.Name}'. No primary-key/s found!");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return SelectByAttribute(tableName, dbPrimaryKeys);
 | 
					            return SelectByAttribute(dbObject._tableName, dbPrimaryKeys);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
@ -70,15 +67,14 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            Type classType = classObject.GetType();
 | 
					            Type classType = classObject.GetType();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Get db-table-name from class
 | 
					            // Read dbObject-attribute
 | 
				
			||||||
            string tableName = Function.GetDbTableName(classType);
 | 
					            DbObject dbObject = ClassAction.Init(classType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Get class db-fields
 | 
					            // Check if 'byPrimaryKey' is possible
 | 
				
			||||||
            Dictionary<string, object> dbPrimaryKeys = new Dictionary<string, object>() { };
 | 
					            if (dbObject.primaryKeyAttributes.Count == 0) throw new InvalidOperationException($"Cannot generate SQL-Query of '{classType.Name}'. No primary-key/s!");
 | 
				
			||||||
            Dictionary<string, object> dbAttributes = new Dictionary<string, object>() { };
 | 
					            Dictionary<string, object> dbPrimaryKeys = Function.ReadFieldData(Function.ConvertToDerivedList(dbObject.primaryKeyAttributes), classObject);
 | 
				
			||||||
            Dictionary<string, object> dbForeignKeys = new Dictionary<string, object>() { };
 | 
					            Dictionary<string, object> dbForeignKeys = Function.ReadFieldData(Function.ConvertToDerivedList(dbObject.foreignKeyAttributes), classObject);
 | 
				
			||||||
            Function.ReadDbClassFields(classObject, ref dbPrimaryKeys, ref dbAttributes, ref dbForeignKeys);
 | 
					            Dictionary<string, object> dbAttributes = Function.ReadFieldData(Function.ConvertToDerivedList(dbObject.attributeAttributes), classObject);
 | 
				
			||||||
            if (dbPrimaryKeys.Count == 0) throw new InvalidOperationException($"Cannot generate SQL-Query of '{classType.Name}'. No primary-key/s found!");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Add foreign-keys to attributes
 | 
					            // Add foreign-keys to attributes
 | 
				
			||||||
            foreach (KeyValuePair<string, object> dbForeignKey in dbForeignKeys)
 | 
					            foreach (KeyValuePair<string, object> dbForeignKey in dbForeignKeys)
 | 
				
			||||||
@ -89,7 +85,7 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System
 | 
				
			|||||||
            // Build set-parameters
 | 
					            // Build set-parameters
 | 
				
			||||||
            object[] paramSet = DbFunction.BuildKeyEqualQuery(dbAttributes, ", ");
 | 
					            object[] paramSet = DbFunction.BuildKeyEqualQuery(dbAttributes, ", ");
 | 
				
			||||||
            // Add SQL-command part
 | 
					            // Add SQL-command part
 | 
				
			||||||
            paramSet[0] = $"UPDATE {tableName} SET "+ paramSet[0];
 | 
					            paramSet[0] = $"UPDATE {dbObject._tableName} SET "+ paramSet[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Build where-parameters
 | 
					            // Build where-parameters
 | 
				
			||||||
            object[] paramWhere = DbFunction.BuildKeyEqualQuery(dbPrimaryKeys, " AND ");
 | 
					            object[] paramWhere = DbFunction.BuildKeyEqualQuery(dbPrimaryKeys, " AND ");
 | 
				
			||||||
@ -111,18 +107,15 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            Type classType = classObject.GetType();
 | 
					            Type classType = classObject.GetType();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Get db-table-name from class
 | 
					            // Read dbObject-attribute
 | 
				
			||||||
            string tableName = Function.GetDbTableName(classType);
 | 
					            DbObject dbObject = ClassAction.Init(classType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Get class db-fields
 | 
					            // Check if 'byPrimaryKey' is possible
 | 
				
			||||||
            Dictionary<string, object> dbPrimaryKeys = new Dictionary<string, object>() { };
 | 
					            if (dbObject.primaryKeyAttributes.Count == 0) throw new InvalidOperationException($"Cannot generate SQL-Query of '{classType.Name}'. No primary-key/s!");
 | 
				
			||||||
            Dictionary<string, object> dbAttributes = new Dictionary<string, object>() { };
 | 
					            Dictionary<string, object> dbPrimaryKeys = Function.ReadFieldData(Function.ConvertToDerivedList(dbObject.primaryKeyAttributes), classObject);
 | 
				
			||||||
            Dictionary<string, object> dbForeignKeys = new Dictionary<string, object>() { };
 | 
					 | 
				
			||||||
            Function.ReadDbClassFields(classObject, ref dbPrimaryKeys, ref dbAttributes, ref dbForeignKeys);
 | 
					 | 
				
			||||||
            if (dbPrimaryKeys.Count == 0) throw new InvalidOperationException($"Cannot generate SQL-Query of '{classType.Name}'. No primary-key/s found!");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Build and return the query
 | 
					            // Build and return the query
 | 
				
			||||||
            return DeleteByAttribute(tableName, dbPrimaryKeys);
 | 
					            return DeleteByAttribute(dbObject._tableName, dbPrimaryKeys);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static string DeleteByAttribute(string tableName, Dictionary<string, object> dbAttributes = null)
 | 
					        public static string DeleteByAttribute(string tableName, Dictionary<string, object> dbAttributes = null)
 | 
				
			||||||
 | 
				
			|||||||
@ -31,20 +31,65 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal static List<BaseAttribute> ConvertToDerivedList(List<DbPrimaryKey> list)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            List<BaseAttribute> derivedList = new List<BaseAttribute>() { };
 | 
				
			||||||
 | 
					            foreach (BaseAttribute key in list)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                derivedList.Add(key);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return derivedList;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        internal static List<BaseAttribute> ConvertToDerivedList(List<DbAttribute> list)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            List<BaseAttribute> derivedList = new List<BaseAttribute>() { };
 | 
				
			||||||
 | 
					            foreach (BaseAttribute key in list)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                derivedList.Add(key);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return derivedList;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        internal static List<BaseAttribute> ConvertToDerivedList(List<DbForeignKey> list)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            List<BaseAttribute> derivedList = new List<BaseAttribute>() { };
 | 
				
			||||||
 | 
					            foreach (BaseAttribute key in list)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                derivedList.Add(key);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return derivedList;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal static Dictionary<string, object> ReadFieldData<T>(List<BaseAttribute> fieldAttributes, T classObject)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Dictionary<string, object> fieldData = new Dictionary<string, object>() { };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach (BaseAttribute attribute in fieldAttributes)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // Read the data and add it
 | 
				
			||||||
 | 
					                fieldData.Add(
 | 
				
			||||||
 | 
					                    attribute._attributeName,
 | 
				
			||||||
 | 
					                    attribute.parentField.GetValue(classObject)
 | 
				
			||||||
 | 
					                    );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return fieldData;   // Return the data
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        internal static void ConvertAttributeToDbAttributes(Type classType, Dictionary<string, object> attributeNameAndValues)
 | 
					        internal static void ConvertAttributeToDbAttributes(Type classType, Dictionary<string, object> attributeNameAndValues)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Dictionary<string, FieldInfo> classFields = ReadDbClassFields(classType);
 | 
					            // Read dbObject-attribute
 | 
				
			||||||
 | 
					            DbObject dbObject = ClassAction.Init(classType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (KeyValuePair<string, object> attributeNameAndValue in attributeNameAndValues)
 | 
					            foreach (KeyValuePair<string, object> attributeNameAndValue in attributeNameAndValues)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                bool nameFound = false;
 | 
					                bool nameFound = false;
 | 
				
			||||||
                foreach (KeyValuePair<string, FieldInfo> classField in classFields)
 | 
					                foreach (BaseAttribute baseAttribute in dbObject.baseAttributes)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (attributeNameAndValue.Key.ToLower() == classField.Value.Name.ToLower())
 | 
					                    if (attributeNameAndValue.Key.ToLower() == baseAttribute.parentField.Name.ToLower())
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        attributeNameAndValues.Remove(attributeNameAndValue.Key);
 | 
					                        attributeNameAndValues.Remove(attributeNameAndValue.Key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        attributeNameAndValues.Add(classField.Key, attributeNameAndValue.Value);
 | 
					                        attributeNameAndValues.Add(baseAttribute._attributeName, attributeNameAndValue.Value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        nameFound = true;
 | 
					                        nameFound = true;
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
@ -56,17 +101,17 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        internal static void ConvertAttributeToDbAttributes(Type classType, List<string> attributeNames)
 | 
					        internal static void ConvertAttributeToDbAttributes(Type classType, List<string> attributeNames)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Dictionary<string, FieldInfo> classFields = ReadDbClassFields(classType);
 | 
					            // Read dbObject-attribute
 | 
				
			||||||
 | 
					            DbObject dbObject = ClassAction.Init(classType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            List<string> dbAttributes = new List<string>() { };
 | 
					            for(int i=0; i< dbObject.baseAttributes.Count; i++)
 | 
				
			||||||
            for(int i=0; i< attributeNames.Count; i++)
 | 
					 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                bool nameFound = false;
 | 
					                bool nameFound = false;
 | 
				
			||||||
                foreach (KeyValuePair<string, FieldInfo> classField in classFields)
 | 
					                foreach (BaseAttribute baseAttribute in dbObject.baseAttributes)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if(attributeNames[i].ToLower() == classField.Value.Name.ToLower())
 | 
					                    if(attributeNames[i].ToLower() == baseAttribute.parentField.Name.ToLower())
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        attributeNames[i] = classField.Key;
 | 
					                        attributeNames[i] = baseAttribute._attributeName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        nameFound = true;
 | 
					                        nameFound = true;
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
@ -77,77 +122,6 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        internal static void ReadDbClassFields<T>(T classObject, ref Dictionary<string, object> dbPrimaryKeys, ref Dictionary<string, object> dbAttributes, ref Dictionary<string, object> dbForeignKeys)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            Type classType = typeof(T);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Reset lists (just in case)
 | 
					 | 
				
			||||||
            dbPrimaryKeys = new Dictionary<string, object>() { };
 | 
					 | 
				
			||||||
            dbAttributes = new Dictionary<string, object>() { };
 | 
					 | 
				
			||||||
            dbForeignKeys = new Dictionary<string, object>() { };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Iterate thru all properties
 | 
					 | 
				
			||||||
            foreach (System.Reflection.FieldInfo fi in classType.GetRuntimeFields())
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                // Check if current field is a db-field
 | 
					 | 
				
			||||||
                if (fi.GetCustomAttribute(typeof(DbPrimaryKey), true) is DbPrimaryKey pkey) // PrimaryKey
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    string dbAttributeName = pkey._attributeName ?? fi.Name;     // If no alternative attribute-name is specified, use the property-name
 | 
					 | 
				
			||||||
                    object value = fi.GetValue(classObject);
 | 
					 | 
				
			||||||
                    dbPrimaryKeys.Add(dbAttributeName, value);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else if (fi.GetCustomAttribute(typeof(DbAttribute), true) is DbAttribute att)   // Attributes
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    string dbAttributeName = att._attributeName ?? fi.Name;     // If no alternative attribute-name is specified, use the property-name
 | 
					 | 
				
			||||||
                    object value = fi.GetValue(classObject);
 | 
					 | 
				
			||||||
                    dbAttributes.Add(dbAttributeName, value);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else if (fi.GetCustomAttribute(typeof(DbForeignKey), true) is DbForeignKey fkey)    // ForeignKeys
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    string dbAttributeName = fkey._attributeName ?? fi.Name;     // If no alternative attribute-name is specified, use the property-name
 | 
					 | 
				
			||||||
                    object value = fi.GetValue(classObject);
 | 
					 | 
				
			||||||
                    dbForeignKeys.Add(dbAttributeName, value);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        internal static Dictionary<string, FieldInfo> ReadDbClassFields(Type classType)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            Dictionary<string, FieldInfo> dbFields = new Dictionary<string, FieldInfo>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Iterate thru all properties
 | 
					 | 
				
			||||||
            foreach (System.Reflection.FieldInfo fi in classType.GetRuntimeFields())
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                // Check if current field is a db-field
 | 
					 | 
				
			||||||
                if (fi.GetCustomAttribute(typeof(DbPrimaryKey), true) is DbPrimaryKey pkey) // PrimaryKey
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    string dbAttributeName = pkey._attributeName ?? fi.Name;     // If no alternative attribute-name is specified, use the property-name
 | 
					 | 
				
			||||||
                    dbFields.Add(dbAttributeName, fi);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else if (fi.GetCustomAttribute(typeof(DbAttribute), true) is DbAttribute att)   // Attributes
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    string dbAttributeName = att._attributeName ?? fi.Name;     // If no alternative attribute-name is specified, use the property-name
 | 
					 | 
				
			||||||
                    dbFields.Add(dbAttributeName, fi);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else if (fi.GetCustomAttribute(typeof(DbForeignKey), true) is DbForeignKey fkey)    // ForeignKeys
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    string dbAttributeName = fkey._attributeName ?? fi.Name;     // If no alternative attribute-name is specified, use the property-name
 | 
					 | 
				
			||||||
                    dbFields.Add(dbAttributeName, fi);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return dbFields;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public static string GetDbTableName(Type classType)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            // Check if class has attribute 'DbObject' and get the database table-name
 | 
					 | 
				
			||||||
            if (!(classType.GetCustomAttribute(typeof(DbObject), true) is DbObject dbObjectAttribute)) throw new InvalidOperationException($"Cannot generate SQL-Query of '{classType.Name}'. Missing Attribute 'DbObject'");
 | 
					 | 
				
			||||||
            string tableName = dbObjectAttribute._tableName ?? classType.Name;    // If no alternative table-name is specified, use the class-name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return tableName;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static string SqlSerialise(object obj)
 | 
					        public static string SqlSerialise(object obj)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user