diff --git a/Database-Attribute_System/Attributes/DbIntermediateForeignObject.cs b/Database-Attribute_System/Attributes/DbIntermediateForeignObject.cs
new file mode 100644
index 0000000..c069052
--- /dev/null
+++ b/Database-Attribute_System/Attributes/DbIntermediateForeignObject.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections;
+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 DbIntermediateForeignObject : Attribute
+ {
+ public Type foreignObjectType;
+
+ public string _intermediateTableName;
+
+ public string _keyName;
+ public string _foreignKeyName;
+
+
+ public DbPrimaryKey foreignPrimaryKeyAttribute;
+
+ public FieldInfo parentField;
+ public DbObject classAttribute;
+
+ ///
+ /// Marks variable as intermediate-object of an dbObject
+ ///
+ /// Table-name of intermediate-table. Must contain primaryKey of this class & target class
+ /// Fieldname of primaryKey associated with the IntermediateObject on this side [m]:n (null if same as primary key) [Only works with 1 primaryKey]
+ /// Fieldname of primaryKey associated with the IntermediateObject on the other side m:[n] (null if same as primary key) [Only works with 1 primaryKey]
+ public DbIntermediateForeignObject(string intermediateTableName, string keyName = null, string foreignKeyName = null)
+ {
+ this._intermediateTableName = intermediateTableName;
+ 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($"IntermediateObject does not support multiple primaryKeys.");
+ // Get primaryKey name if none is set
+ if (_keyName == null) _keyName = classAttribute.primaryKeyAttributes[0]._attributeName;
+
+ if (!(fi.FieldType is IList && fi.FieldType.IsGenericType)) // 1:m
+ throw new InvalidOperationException($"IntermediateObject has to be typeof(List). Maybe you meant to use DbForeignObject or DbReverseForeignObject for 1:m or 1:1 relations.");
+
+ // Check the generic list and get inner-type
+ Type foreignObjectType = null;
+ foreach (Type interfaceType in fi.FieldType.GetInterfaces())
+ {
+ if (interfaceType.IsGenericType &&
+ interfaceType.GetGenericTypeDefinition()
+ == typeof(IList<>))
+ {
+ foreignObjectType = fi.FieldType.GetGenericArguments()[0];
+ break;
+ }
+ }
+ if (foreignObjectType == null) throw new InvalidOperationException("Could not read innter-type of generic-list!");
+
+ // Now get the primaryKey from my foreignObject
+ DbObject foreignDbObject = ClassAction.Init(foreignObjectType);
+ // Check the primaryKey/s
+ if (foreignDbObject.primaryKeyAttributes.Count < 1) throw new InvalidOperationException($"'{foreignDbObject.parentClassType.Name}' does not have a primaryKey.");
+ if (foreignDbObject.primaryKeyAttributes.Count > 1) throw new InvalidOperationException($"IntermediateObject does not support multiple primaryKeys. (Found '{foreignDbObject.primaryKeyAttributes.Count}' in '{foreignDbObject.parentClassType.Name}')");
+ // Save it
+ foreignPrimaryKeyAttribute = foreignDbObject.primaryKeyAttributes[0];
+
+ if (_foreignKeyName == null) _foreignKeyName = foreignPrimaryKeyAttribute._attributeName;
+ }
+ }
+}
diff --git a/Database-Attribute_System/Attributes/DbObject.cs b/Database-Attribute_System/Attributes/DbObject.cs
index 9adfb74..4f33908 100644
--- a/Database-Attribute_System/Attributes/DbObject.cs
+++ b/Database-Attribute_System/Attributes/DbObject.cs
@@ -21,6 +21,7 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System.Attributes
public List foreignKeyAttributes = new List() { };
public List foreignObjectAttributes = new List() { };
public List reverseForeignObjectAttributes = new List() { };
+ public List intermediateObjectAttributes = new List() { };
///
/// Marks variable as database-table
@@ -74,6 +75,11 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System.Attributes
rfobj.Init(fi, this);
this.reverseForeignObjectAttributes.Add(rfobj);
}
+ else if (fi.GetCustomAttribute(typeof(DbIntermediateForeignObject), true) is DbIntermediateForeignObject iobj) // ReverseForeignObjects
+ {
+ iobj.Init(fi, this);
+ this.intermediateObjectAttributes.Add(iobj);
+ }
}
catch(InvalidOperationException ex)
{
diff --git a/Database-Attribute_System/ClassAction.cs b/Database-Attribute_System/ClassAction.cs
index b882196..d943356 100644
--- a/Database-Attribute_System/ClassAction.cs
+++ b/Database-Attribute_System/ClassAction.cs
@@ -278,7 +278,6 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System
DbObject dbObject = ClassAction.Init(classType);
// Resolve foreignObjects
-
foreach (DbForeignObject foreignObjectAtt in dbObject.foreignObjectAttributes)
{
object foreignObject_value = foreignObjectAtt.parentField.GetValue(classObject);
@@ -322,6 +321,62 @@ namespace eu.railduction.netcore.dll.Database_Attribute_System
}
}
+ // Resolve intermediateForeignObjects
+ foreach (DbIntermediateForeignObject intermediateForeignObjectAtt in dbObject.intermediateObjectAttributes)
+ {
+ object intermediateForeignObject_value = intermediateForeignObjectAtt.parentField.GetValue(classObject);
+
+ // When its empty, get it & set it
+ if (intermediateForeignObject_value == null)
+ {
+ // Generate & set attribute-set
+ Dictionary attributes = new Dictionary();
+ attributes.Add(intermediateForeignObjectAtt._keyName, dbObject.primaryKeyAttributes[0].parentField.GetValue(classObject));
+
+ string query = QueryBuilder.SelectByAttribute(intermediateForeignObjectAtt._intermediateTableName, attributes); // Generate query
+ List> dataSet = queryExecutor(query); // Execute
+ // Extract data
+ List