public static GXDeleteArgs Remove <TItem, TDestination>(TItem[] items, TDestination[] collections) { object collectionId, id; if (items == null || collections == null || items.Length == 0 || collections.Length == 0) { throw new ArgumentNullException("Invalid value"); } Type itemType = typeof(TItem); Type collectionType = typeof(TDestination); GXSerializedItem si = GXSqlBuilder.FindRelation(itemType, collectionType); if (si.Relation == null || si.Relation.RelationMapTable == null) { throw new ArgumentNullException("Invalid collection"); } GXDeleteArgs args = Delete(si.Relation.RelationMapTable.Relation.PrimaryTable); args.Parent.Updated = true; GXSerializedItem siItem = GXSqlBuilder.FindRelation(collectionType, itemType); foreach (TDestination c in collections) { //Get collection id. collectionId = si.Relation.RelationMapTable.Relation.ForeignId.Get(c); foreach (TItem it in items) { object target = GXJsonParser.CreateInstance(si.Relation.RelationMapTable.Relation.PrimaryTable); si.Relation.RelationMapTable.Relation.PrimaryId.Set(target, collectionId); //Get item id. id = siItem.Relation.RelationMapTable.Relation.ForeignId.Get(it); siItem.Relation.RelationMapTable.Relation.PrimaryId.Set(target, id); Expression <Func <object, object> > t = q => target; args.Where.List.Add(new KeyValuePair <WhereType, LambdaExpression>(WhereType.Or, t)); } } return(args); }
private void GetRelations(Type type, List <GXJoin> joinList, List <Type> tables, Dictionary <Type, List <string> > columns, bool getRelations) { if (!tables.Contains(type)) { //TODO: lisää shared table attribute. bool ignorebaseType = false; foreach (var it in tables) { if (GXDbHelpers.IsSharedTable(it) && type.IsAssignableFrom(it.BaseType)) { ignorebaseType = true; break; } } if (ignorebaseType) { return; } tables.Add(type); Type tp; bool added; List <string> excluded = null; List <string> cols = null; string tableName = null; if (columns != null && columns.ContainsKey(type)) { cols = columns[type]; if (cols.Contains("*")) { cols = null; } } Dictionary <string, GXSerializedItem> properties = GXSqlBuilder.GetProperties(type); foreach (var it in properties) { if (cols != null && !cols.Contains(it.Key)) { continue; } if (!IsExcluded(it.Key, excluded)) { if (it.Value.Relation != null && getRelations) { GXJoin j = new GXJoin(); tp = it.Value.Relation.PrimaryTable; j.Table1Type = tp; bool shared = GXDbHelpers.IsSharedTable(tp); if (shared || GXDbHelpers.IsAliasName(tp)) { j.Alias1 = GXDbHelpers.OriginalTableName(tp); } j.Table2Type = it.Value.Relation.ForeignTable; j.UpdateTables(tp, it.Value.Relation.ForeignTable); //If nullable. Type tp2 = it.Value.Relation.ForeignId.Type; j.AllowNull1 = !shared && tp2.IsGenericType && tp2.GetGenericTypeDefinition() == typeof(Nullable <>); if (!j.AllowNull1) { tp2 = it.Value.Relation.PrimaryId.Type; j.AllowNull2 = !GXDbHelpers.IsSharedTable(it.Value.Relation.ForeignTable) && tp2.IsGenericType && tp2.GetGenericTypeDefinition() == typeof(Nullable <>); } if (GXDbHelpers.IsSharedTable(it.Value.Relation.ForeignTable) || GXDbHelpers.IsAliasName(it.Value.Relation.ForeignTable)) { j.Alias2 = GXDbHelpers.OriginalTableName(it.Value.Relation.ForeignTable); } if (it.Value.Relation.RelationType == RelationType.OneToOne || it.Value.Relation.RelationType == RelationType.Relation) { j.Column2 = GXDbHelpers.GetColumnName(it.Value.Relation.PrimaryId.Relation.ForeignId.Target as PropertyInfo, Parent.Settings.ColumnQuotation); j.Column1 = GXDbHelpers.GetColumnName(it.Value.Relation.PrimaryId.Target as PropertyInfo, Parent.Settings.ColumnQuotation); if (tables.Contains(it.Value.Relation.ForeignTable)) { continue; } //If nullable. tp2 = it.Value.Relation.PrimaryId.Relation.ForeignId.Type; j.AllowNull1 = !shared && tp2.IsGenericType && tp2.GetGenericTypeDefinition() == typeof(Nullable <>); if (!j.AllowNull1) { tp2 = it.Value.Relation.PrimaryId.Relation.PrimaryId.Type; j.AllowNull2 = !GXDbHelpers.IsSharedTable(it.Value.Relation.ForeignTable) && tp2.IsGenericType && tp2.GetGenericTypeDefinition() == typeof(Nullable <>); } } else if (it.Value.Relation.RelationType == RelationType.OneToMany) { j.Column1 = GXDbHelpers.GetColumnName(it.Value.Relation.PrimaryId.Relation.ForeignId.Target as PropertyInfo, Parent.Settings.ColumnQuotation); j.Column2 = GXDbHelpers.GetColumnName(it.Value.Relation.PrimaryId.Target as PropertyInfo, Parent.Settings.ColumnQuotation); //If nullable. tp2 = it.Value.Relation.ForeignId.Type; j.AllowNull1 = !shared && tp2.IsGenericType && tp2.GetGenericTypeDefinition() == typeof(Nullable <>); if (!j.AllowNull1) { tp2 = it.Value.Relation.PrimaryId.Type; j.AllowNull2 = !GXDbHelpers.IsSharedTable(it.Value.Relation.ForeignTable) && tp2.IsGenericType && tp2.GetGenericTypeDefinition() == typeof(Nullable <>); } } else if (it.Value.Relation.RelationType == RelationType.ManyToMany) { j.Table2Type = it.Value.Relation.RelationMapTable.Relation.PrimaryTable; j.UpdateTables(tp, it.Value.Relation.RelationMapTable.Relation.PrimaryTable); j.Column2 = GXDbHelpers.GetColumnName(GXSqlBuilder.FindRelation(it.Value.Relation.RelationMapTable.Relation.PrimaryTable, tp).Target as PropertyInfo, Parent.Settings.ColumnQuotation); j.Column1 = GXDbHelpers.GetColumnName(GXSqlBuilder.FindUnique(tp).Target as PropertyInfo, Parent.Settings.ColumnQuotation); added = false; //Check that join is not added already. string j1 = j.Table1; string j2 = j.Table2; foreach (var it4 in joinList) { string t1 = it4.Table1; string t2 = it4.Table2; if ((j1 == t1 && j2 == t2) || (j2 == t1 && j1 == t2)) { added = true; break; } } if (!added) { joinList.Add(j); j = new GXJoin(); Type tmp = it.Value.Type; j.AllowNull1 = !!GXDbHelpers.IsSharedTable(tmp) && tmp.IsGenericType && tmp.GetGenericTypeDefinition() == typeof(Nullable <>); j.UpdateTables(it.Value.Relation.RelationMapTable.Relation.PrimaryTable, it.Value.Relation.ForeignTable); j.Column1 = GXDbHelpers.GetColumnName(it.Value.Relation.RelationMapTable.Target as PropertyInfo, Parent.Settings.ColumnQuotation); j.Column2 = GXDbHelpers.GetColumnName(it.Value.Relation.ForeignId.Target as PropertyInfo, Parent.Settings.ColumnQuotation); joinList.Add(j); tables.Add(it.Value.Relation.RelationMapTable.Relation.PrimaryTable); if (cols != null) { tables.Add(it.Value.Relation.ForeignTable); } } j = null; } if (j != null) { //Check that join is not added already. added = false; string j1 = j.Table1; string j2 = j.Table2; int index = -1; foreach (var it4 in joinList) { string t1 = it4.Table1; string t2 = it4.Table2; if ((j1 == t1 && j2 == t2) || (j2 == t1 && j1 == t2)) { added = true; break; } if (j.Alias2 != null && it4.Alias2 == j.Alias2) { ++index; } } //If we have multiple referenced to same table. if (index != -1) { j.Index = index + 1; } if (!added) { joinList.Add(j); } } if (cols == null || cols.Contains(it.Key)) { GetRelations(it.Value.Relation.ForeignTable, joinList, tables, columns, getRelations); } } } else { System.Diagnostics.Debug.WriteLine("Column " + tableName + "." + it.Key + " Skipped."); } } } }
/// <summary> /// Update DB relations. /// </summary> /// <param name="mainType"></param> /// <param name="s"></param> private static void UpdateRelations(Type mainType, GXSerializedItem s, bool primaryData, Dictionary <Type, GXRelationTable> relationTable) { Type type; if (primaryData) { s.Relation = new GXRelationTable(); s.Relation.Column = s; s.Relation.PrimaryTable = mainType; s.Relation.PrimaryId = s; if ((s.Attributes & Attributes.ForeignKey) != 0) { ForeignKeyAttribute[] fks = ((ForeignKeyAttribute[])(s.Target as PropertyInfo).GetCustomAttributes(typeof(ForeignKeyAttribute), false)); ForeignKeyAttribute fk; if (fks.Length == 0) { fk = null; type = null; } else { fk = fks[0]; type = fk.Type; } //If type is not give in ForeignKeyAttribute. if (type == null) { type = s.Type; if (typeof(IEnumerable).IsAssignableFrom(type)) { type = GXInternal.GetPropertyType(type); } } s.Relation.ForeignTable = type; if (fk != null && fk.MapTable != null) { s.Relation.RelationType = RelationType.ManyToMany; } else if (s.Type != typeof(string) && typeof(System.Collections.IEnumerable).IsAssignableFrom(s.Type)) { s.Relation.RelationType = RelationType.OneToMany; s.Relation.PrimaryId = GXSqlBuilder.FindRelation(type, mainType); if (s.Relation.PrimaryId == null) { throw new Exception(string.Format("Relation create failed. Foreign table '{0}' do not have relation to table '{1}'.", GXDbHelpers.GetTableName(type, false, null), GXDbHelpers.OriginalTableName(mainType))); } } else { s.Relation.RelationType = RelationType.OneToOne; } } else if ((s.Attributes & Attributes.Relation) != 0) { RelationAttribute ra = ((RelationAttribute[])(s.Target as PropertyInfo).GetCustomAttributes(typeof(RelationAttribute), false))[0]; type = ra.Target; if (type == null) { type = s.Type; } if (typeof(IEnumerable).IsAssignableFrom(type)) { type = GXInternal.GetPropertyType(type); } s.Relation.ForeignTable = type; } } else { if ((s.Attributes & Attributes.ForeignKey) != 0) { ForeignKeyAttribute[] fks = ((ForeignKeyAttribute[])(s.Target as PropertyInfo).GetCustomAttributes(typeof(ForeignKeyAttribute), false)); ForeignKeyAttribute fk; if (fks.Length == 0) { fk = null; type = null; } else { fk = fks[0]; type = fk.Type; } //If type is not give in ForeignKeyAttribute. if (type == null) { type = s.Type; if (typeof(IEnumerable).IsAssignableFrom(type)) { type = GXInternal.GetPropertyType(type); } } GXSerializedItem secondary = FindUnique(type); if (secondary == null) { throw new Exception(string.Format("Table {0} Relation create failed. Class must be derived from IUnique or target type must set in ForeignKey or Relation attribute.", GXDbHelpers.GetTableName(mainType, true, '\'', null))); } s.Relation.ForeignId = secondary; //Update relation map fields. if (fk != null && fk.MapTable != null) { foreach (var it in GetProperties(fk.MapTable)) { if ((it.Value.Attributes & Attributes.ForeignKey) != 0 && s.Relation.ForeignTable == it.Value.Relation.ForeignTable) { s.Relation.RelationMapTable = it.Value; break; } } } } else if ((s.Attributes & Attributes.Relation) != 0) { RelationAttribute ra = ((RelationAttribute[])(s.Target as PropertyInfo).GetCustomAttributes(typeof(RelationAttribute), false))[0]; type = ra.Target; if (type == null) { type = s.Type; } if (typeof(IEnumerable).IsAssignableFrom(type)) { type = GXInternal.GetPropertyType(type); } GXSerializedItem secondary = FindUnique(type); if (secondary == null) { throw new Exception(string.Format("Table {0} Relation create failed. Class must be derived from IUnique or target type must set in ForeignKey or Relation attribute.", GXDbHelpers.GetTableName(mainType, true, '\'', null))); } s.Relation.ForeignId = secondary; } } }