|  | @@ -80,6 +80,8 @@ namespace InABox.Core
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          IEnumerable<DataTable> DefaultTables { get; }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        void AddTable(string alias, CoreTable table, bool isdefault = false);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          void AddTable(Type type, CoreTable table, bool isdefault = false, string? alias = null);
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
		
			
				|  |  |          /// Adds a table to the datamodel.
 | 
	
	
		
			
				|  | @@ -96,6 +98,7 @@ namespace InABox.Core
 | 
	
		
			
				|  |  |          /// </param>
 | 
	
		
			
				|  |  |          void AddTable<TType>(Filter<TType>? filter, Columns<TType>? columns, bool isdefault = false, string? alias = null, bool shouldLoad = true);
 | 
	
		
			
				|  |  |          void LinkTable(Type parenttype, string parentcolumn, Type childtype, string childcolumn, string? parentalias = null, string? childalias = null, bool isLookup = false);
 | 
	
		
			
				|  |  | +        void LinkTable(Type parenttype, string parentcolumn, string childalias, string childcolumn, string? parentalias = null, bool isLookup = false);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          void LinkTable<TParent, TChild>(Expression<Func<TParent, object>> parent, Expression<Func<TChild, object>> child, string? parentalias = null,
 | 
	
		
			
				|  |  |              string? childalias = null, bool isLookup = false);
 | 
	
	
		
			
				|  | @@ -151,6 +154,7 @@ namespace InABox.Core
 | 
	
		
			
				|  |  |          CoreTable GetTable<TType>(string? alias = null);
 | 
	
		
			
				|  |  |          void SetTableData(Type type, CoreTable tableData, string? alias = null);
 | 
	
		
			
				|  |  |          bool HasTable(Type type, string? alias = null);
 | 
	
		
			
				|  |  | +        bool HasTable<TType>(string? alias = null);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          void LoadModel(IEnumerable<string> requiredTables, Dictionary<string, IQueryDef>? requiredQueries = null);
 | 
	
		
			
				|  |  |          void LoadModel(IEnumerable<string> requiredTables, params IDataModelQueryDef[] requiredQueries);
 | 
	
	
		
			
				|  | @@ -172,16 +176,7 @@ namespace InABox.Core
 | 
	
		
			
				|  |  |              AddTable(new Filter<User>(x => x.ID).IsEqualTo(ClientFactory.UserGuid), null, true);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        public Dictionary<Type, CoreTable> AsDictionary
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            get
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                var result = new Dictionary<Type, CoreTable>();
 | 
	
		
			
				|  |  | -                foreach (var alias in _tables.Keys)
 | 
	
		
			
				|  |  | -                    result[_tables[alias].Type] = _tables[alias].Table;
 | 
	
		
			
				|  |  | -                return result;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +        public IEnumerable<KeyValuePair<string, DataModelTable>> ModelTables => _tables;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          public abstract string Name { get; }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -203,12 +198,17 @@ namespace InABox.Core
 | 
	
		
			
				|  |  |              foreach(var (key, table) in _tables)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  var current = table.Table.Columns.ToDictionary(x => x.ColumnName, x => x);
 | 
	
		
			
				|  |  | -                var additional = Columns.Create(table.Type);
 | 
	
		
			
				|  |  | -                foreach (var column in CoreUtils.GetColumnNames(table.Type, x => true))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                IColumns? additional = null;
 | 
	
		
			
				|  |  | +                if(table.Type != null)
 | 
	
		
			
				|  |  |                  {
 | 
	
		
			
				|  |  | -                    if (!current.ContainsKey(column))
 | 
	
		
			
				|  |  | +                    additional = Columns.Create(table.Type);
 | 
	
		
			
				|  |  | +                    foreach (var column in CoreUtils.GetColumnNames(table.Type, x => true))
 | 
	
		
			
				|  |  |                      {
 | 
	
		
			
				|  |  | -                        additional.Add(column);
 | 
	
		
			
				|  |  | +                        if (!current.ContainsKey(column))
 | 
	
		
			
				|  |  | +                        {
 | 
	
		
			
				|  |  | +                            additional.Add(column);
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -325,7 +325,9 @@ namespace InABox.Core
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          public class DataModelTable
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            public DataModelTable(Type type, CoreTable table, bool isDefault, IFilter? filter, IColumns? columns, bool shouldLoad = true)
 | 
	
		
			
				|  |  | +            private bool shouldLoad;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            public DataModelTable(Type? type, CoreTable table, bool isDefault, IFilter? filter, IColumns? columns, bool shouldLoad = true)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  Type = type;
 | 
	
		
			
				|  |  |                  Table = table;
 | 
	
	
		
			
				|  | @@ -335,7 +337,7 @@ namespace InABox.Core
 | 
	
		
			
				|  |  |                  ShouldLoad = shouldLoad;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            public Type Type { get; }
 | 
	
		
			
				|  |  | +            public Type? Type { get; }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              public CoreTable Table { get; set; }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -345,7 +347,14 @@ namespace InABox.Core
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              public IColumns? Columns { get; set; }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            public bool ShouldLoad { get; set; }
 | 
	
		
			
				|  |  | +            public bool ShouldLoad
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                get => shouldLoad && Type != null;
 | 
	
		
			
				|  |  | +                set
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    shouldLoad = value;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          #region New Load Methods
 | 
	
	
		
			
				|  | @@ -383,14 +392,19 @@ namespace InABox.Core
 | 
	
		
			
				|  |  |              var relation = _relationships.Where(x => x.ChildTable == tableName).FirstOrDefault();
 | 
	
		
			
				|  |  |              if (relation != null)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  | -                var subFilter = (typeof(DataModel).GetMethod(nameof(GetSubquery), BindingFlags.NonPublic | BindingFlags.Instance)
 | 
	
		
			
				|  |  | +                var table = _tables[relation.ParentTable];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                if(table.Type != null)
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    var subFilter = (typeof(DataModel).GetMethod(nameof(GetSubquery), BindingFlags.NonPublic | BindingFlags.Instance)
 | 
	
		
			
				|  |  |                      .MakeGenericMethod(_tables[relation.ParentTable].Type, typeof(TType))
 | 
	
		
			
				|  |  |                      .Invoke(this, new object?[] { relation, requiredQueries }) as Filter<TType>)!;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                if (newFilter != null)
 | 
	
		
			
				|  |  | -                    newFilter.And(subFilter);
 | 
	
		
			
				|  |  | -                else
 | 
	
		
			
				|  |  | -                    newFilter = subFilter;
 | 
	
		
			
				|  |  | +                    if (newFilter != null)
 | 
	
		
			
				|  |  | +                        newFilter.And(subFilter);
 | 
	
		
			
				|  |  | +                    else
 | 
	
		
			
				|  |  | +                        newFilter = subFilter;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              return newFilter;
 | 
	
	
		
			
				|  | @@ -465,19 +479,19 @@ namespace InABox.Core
 | 
	
		
			
				|  |  |              return _relationships.Any(x => x.ChildTable == tableName);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        public static string TableName(Type type, string? alias = null)
 | 
	
		
			
				|  |  | +        public static string TableName(Type? type, string? alias = null)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            return string.IsNullOrWhiteSpace(alias) ? type.EntityName().Split('.').Last() : alias;
 | 
	
		
			
				|  |  | +            return string.IsNullOrWhiteSpace(alias) ? (type ?? throw new Exception("No type or alias given!")).EntityName().Split('.').Last() : alias;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        private void CheckTable(Type type, string? alias = null)
 | 
	
		
			
				|  |  | +        private void CheckTable(Type? type, string? alias = null)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              var name = TableName(type, alias);
 | 
	
		
			
				|  |  |              if (!_tables.ContainsKey(name))
 | 
	
		
			
				|  |  |                  throw new Exception(string.Format("No Table for {0}", name));
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        public void AddTable(Type type, CoreTable table, bool isdefault = false, string? alias = null)
 | 
	
		
			
				|  |  | +        public void AddTable(Type? type, CoreTable table, bool isdefault = false, string? alias = null)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              var name = TableName(type, alias);
 | 
	
		
			
				|  |  |              if (!_tables.ContainsKey(name))
 | 
	
	
		
			
				|  | @@ -499,8 +513,10 @@ namespace InABox.Core
 | 
	
		
			
				|  |  |                  throw new Exception(string.Format("[{0}] does not exist in this data model!", name));
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +        public void LinkTable(Type parenttype, string parentcolumn, string childalias, string childcolumn, string? parentalias = null, bool isLookup = false) =>
 | 
	
		
			
				|  |  | +            LinkTable(parenttype, parentcolumn, null, childcolumn, parentalias, childalias, isLookup);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        public void LinkTable(Type parenttype, string parentcolumn, Type childtype, string childcolumn, string? parentalias = null,
 | 
	
		
			
				|  |  | +        public void LinkTable(Type parenttype, string parentcolumn, Type? childtype, string childcolumn, string? parentalias = null,
 | 
	
		
			
				|  |  |              string? childalias = null, bool isLookup = false)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              CheckTable(parenttype, parentalias);
 | 
	
	
		
			
				|  | @@ -524,11 +540,14 @@ namespace InABox.Core
 | 
	
		
			
				|  |  |              var name = TableName(type, alias);
 | 
	
		
			
				|  |  |              return _tables.ContainsKey(name);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +        public bool HasTable<T>(string? alias = null) => HasTable(typeof(T), alias);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          #endregion
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          #region Adding & Linking Tables
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        public void AddTable(string alias, CoreTable table, bool isdefault = false) => AddTable(null, table, isdefault, alias);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          public void AddTable<TType>(Filter<TType>? filter, Columns<TType>? columns, bool isdefault = false, string? alias = null, bool shouldLoad = true)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              var name = TableName<TType>(alias);
 |