Added DbReverseForeignObject

Removed method SqlSerialise(DateTime ...)
master
Railz 6 years ago
parent aca99302dd
commit 111b3bf7ce

@ -20,6 +20,7 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System.Attributes
public List<DbAttribute> attributeAttributes = new List<DbAttribute>() { }; public List<DbAttribute> attributeAttributes = new List<DbAttribute>() { };
public List<DbForeignKey> foreignKeyAttributes = new List<DbForeignKey>() { }; public List<DbForeignKey> foreignKeyAttributes = new List<DbForeignKey>() { };
public List<DbForeignObject> foreignObjectAttributes = new List<DbForeignObject>() { }; public List<DbForeignObject> foreignObjectAttributes = new List<DbForeignObject>() { };
public List<DbReverseForeignObject> reverseForeignObjectAttributes = new List<DbReverseForeignObject>() { };
/// <summary> /// <summary>
/// Marks variable as database-table /// Marks variable as database-table
@ -68,6 +69,11 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System.Attributes
this.foreignObjectAttributes.Add(fobj); this.foreignObjectAttributes.Add(fobj);
} }
else if (fi.GetCustomAttribute(typeof(DbReverseForeignObject), true) is DbReverseForeignObject rfobj) // ReverseForeignObjects
{
rfobj.Init(fi, this);
this.reverseForeignObjectAttributes.Add(rfobj);
}
} }
catch(InvalidOperationException ex) catch(InvalidOperationException ex)
{ {

@ -0,0 +1,60 @@
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 DbReverseForeignObject : Attribute
{
public Type foreignObjectType;
public string _foreignKeyName;
public DbForeignKey foreignKeyAttribute;
public FieldInfo parentField;
public DbObject classAttribute;
/// <summary>
/// Marks variable as reverse-foreign-object of an dbObject
/// </summary>
/// <param name="foreignKeyName">Fieldname of primaryKey associated with the reverseForeignObject (null if same as primary key) [Only works with 1 primaryKey]</param>
public DbReverseForeignObject(string foreignKeyName = null)
{
this._foreignKeyName = foreignKeyName;
}
public void Init(FieldInfo fi, DbObject classAttribute)
{
this.parentField = fi;
this.classAttribute = classAttribute;
this.foreignObjectType = fi.FieldType;
// Init foreign-object class
DbObject foreignClassAttribute = ClassAction.Init(this.foreignObjectType);
if (classAttribute.primaryKeyAttributes.Count < 1) throw new InvalidOperationException($"'{classAttribute.parentClassType.Name}' does not have a primaryKey.");
if (classAttribute.primaryKeyAttributes.Count > 1) throw new InvalidOperationException($"ReverseForeignObject does not support multiple primaryKeys.");
// Get primaryKey name if none is set
if (_foreignKeyName == null) _foreignKeyName = classAttribute.primaryKeyAttributes[0]._attributeName;
// Check if my primary-key is set in the foreign-class as foreignKey
DbPrimaryKey primaryKey = classAttribute.primaryKeyAttributes[0];
foreach (DbForeignKey foreignKey in foreignClassAttribute.foreignKeyAttributes)
{
if (primaryKey._attributeName.ToLower() == foreignKey._attributeName.ToLower()) // Name matches
if (primaryKey.parentField.GetType() == foreignKey.parentField.GetType()) // Type matches
{
foreignKeyAttribute = foreignKey;
}
else
// Same name, but wrong type
throw new InvalidOperationException($"ForeignObject='{foreignClassAttribute.parentClassType.Name}' has invalid type foreignKey='{foreignKey.parentField.Name}' for object='{classAttribute.parentClassType.Name}' with primaryKey='{primaryKey.parentField.Name}'.");
}
// No match
if (foreignKeyAttribute == null) throw new InvalidOperationException($"ForeignObject='{foreignClassAttribute.parentClassType.Name}' is missing foreignKey for object='{classAttribute.parentClassType.Name}' with primaryKey='{primaryKey.parentField.Name}'.");
}
}
}

@ -1,5 +1,6 @@
using eu.railduction.netcore.dll.Database_Attribute_System.Attributes; using eu.railduction.netcore.dll.Database_Attribute_System.Attributes;
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
@ -126,7 +127,7 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System
} }
// If no data was found matching this field // 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}'"); if (!dataMatchFound) throw new InvalidOperationException($"PrimaryKey='{primaryKeyAtt.parentField.Name}' is missing.");
} }
ResolveByPrimaryKey<T>(obj, queryExecutor); ResolveByPrimaryKey<T>(obj, queryExecutor);
@ -276,22 +277,75 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System
// Read dbObject-attribute // Read dbObject-attribute
DbObject dbObject = ClassAction.Init(classType); DbObject dbObject = ClassAction.Init(classType);
// Resolve foreignObjects
foreach (DbForeignObject foreignObjectAtt in dbObject.foreignObjectAttributes) foreach (DbForeignObject foreignObjectAtt in dbObject.foreignObjectAttributes)
{ {
object foreignObject_value = foreignObjectAtt.parentField.GetValue(classObject); object foreignObject_value = foreignObjectAtt.parentField.GetValue(classObject);
// When its empty, get it // When its empty, get it & set it
if(foreignObject_value == null) if(foreignObject_value == null)
{ {
foreignObject_value = GetByPrimaryKey<T>(classType, foreignObjectAtt.foreignKeyAttribute.parentField.GetValue(classObject), queryExecutor); foreignObject_value = GetByPrimaryKey<T>(classType, foreignObjectAtt.foreignKeyAttribute.parentField.GetValue(classObject), queryExecutor);
foreignObjectAtt.parentField.SetValue(classObject, foreignObject_value);
} }
// Recursive resolving // Recursive resolving
if (max_depth - 1 > 0) if (max_depth > 1)
{ {
// Go recursively into the next class
ResolveForeignKeys(foreignObject_value, queryExecutor, max_depth - 1); ResolveForeignKeys(foreignObject_value, queryExecutor, max_depth - 1);
} }
} }
// Resolve reverseForeignObjects
foreach (DbReverseForeignObject reverseForeignObjectAtt in dbObject.reverseForeignObjectAttributes)
{
object reverseForeignObject_value = reverseForeignObjectAtt.parentField.GetValue(classObject);
// When its empty, get it & set it
if (reverseForeignObject_value == null)
{
// Generate & set attribute-set
Dictionary<string, object> attributes = new Dictionary<string, object>();
attributes.Add(reverseForeignObjectAtt._foreignKeyName, dbObject.primaryKeyAttributes[0].parentField.GetValue(classObject));
List<object> values = GetListByAttribute<object>(reverseForeignObjectAtt.foreignKeyAttribute.classAttribute.parentClassType, attributes, queryExecutor);
if(values.Count == 0) throw new InvalidOperationException($"'{reverseForeignObjectAtt.parentField.Name}' could not been resolved. ReverseForeignObject returned '{values.Count}' values.");
// Check for type to determen 1:1 or 1:m
Type reverseForeignObject_type = reverseForeignObjectAtt.parentField.GetType();
if (reverseForeignObject_type is IList && reverseForeignObject_type.IsGenericType) // List, so 1:m
{
reverseForeignObject_value = values;
}
else // Not list, so 1:1
{
if (values.Count > 1) throw new InvalidOperationException($"'{reverseForeignObjectAtt.parentField.Name}' could not been resolved as ReverseForeignObject returned '{values.Count}' values. (Is it 1:1 instead of 1:m?)");
reverseForeignObject_value = values[0];
}
reverseForeignObjectAtt.parentField.SetValue(classObject, reverseForeignObject_value);
}
// Recursive resolving
if (max_depth > 1)
{
if (reverseForeignObject_value is IList) // 1:m
{
// If we have a list of objects, we need to recursively go into each one
foreach(object value in (IList)reverseForeignObject_value)
{
ResolveForeignKeys(value, queryExecutor, max_depth - 1);
}
}
else // 1:1
{
// Go recursively into the next class
ResolveForeignKeys(reverseForeignObject_value, queryExecutor, max_depth - 1);
}
}
}
} }
} }
} }

@ -14,11 +14,6 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System
return str_cpy; return str_cpy;
} }
public static string SqlSerialise(DateTime dt, string format = "yyyy-MM-dd HH:mm:ss")
{
return dt.ToString(format);
}
// Recursive object[] copying // Recursive object[] copying
internal static void RecursiveParameterCopying(ref List<object> paramz, object[] objects) internal static void RecursiveParameterCopying(ref List<object> paramz, object[] objects)
{ {
@ -124,24 +119,24 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System
public static string SqlSerialise(object obj) public static string SqlSerialise(object obj)
{ {
if (obj == null) // Handle null if (obj == null || obj is DBNull) // Handle null
{ {
return "null"; return "null";
} }
else if (obj.GetType() == typeof(string)) // Handle strings else if (obj is string) // Handle strings
{ {
return "'" + SqlEscape((string)obj) + "'"; // wrap in sql-brackets and escape sql, if any return "'" + SqlEscape((string)obj) + "'"; // wrap in sql-brackets and escape sql, if any
} }
else if (obj.GetType() == typeof(byte) || obj.GetType() == typeof(int) || obj.GetType() == typeof(float) || obj.GetType() == typeof(double)) // Handle int, float & double else if (obj is byte || obj is int || obj is float || obj is double) // Handle int, float & double
{ {
return obj.ToString().Replace(",", "."); // just format to string and form comma to sql-comma return obj.ToString().Replace(",", "."); // just format to string and form comma to sql-comma
} }
else if (obj.GetType() == typeof(DateTime)) // Handle DateTime else if (obj is DateTime) // Handle DateTime
{ {
DateTime dateTime = (DateTime)obj; DateTime dateTime = (DateTime)obj;
return "'" + SqlSerialise(dateTime) + "'"; // wrap in sql-brackets and convert to sql-datetime return "'" + dateTime.ToString("yyyy-MM-dd HH:mm:ss") + "'"; // wrap in sql-brackets and convert to sql-datetime
} }
else if (obj.GetType() == typeof(Guid)) // Handle Guid else if (obj is Guid) // Handle Guid
{ {
string guid = ((Guid)obj).ToString(); // Get Guid as string string guid = ((Guid)obj).ToString(); // Get Guid as string
return "'" + guid + "'"; // wrap in sql-brackets return "'" + guid + "'"; // wrap in sql-brackets

Loading…
Cancel
Save