async Task Save <TEntity>(TEntity entity, TypeDescriptor declaringTypeDescriptor, bool @async) { await this.Insert(entity, null, @async); TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(typeof(TEntity)); for (int i = 0; i < typeDescriptor.ComplexPropertyDescriptors.Count; i++) { //entity.TOther ComplexPropertyDescriptor navPropertyDescriptor = typeDescriptor.ComplexPropertyDescriptors[i]; if (declaringTypeDescriptor != null && navPropertyDescriptor.PropertyType == declaringTypeDescriptor.Definition.Type) { continue; } await this.SaveOneToOne(navPropertyDescriptor, entity, typeDescriptor, @async); } for (int i = 0; i < typeDescriptor.CollectionPropertyDescriptors.Count; i++) { //entity.List CollectionPropertyDescriptor collectionPropertyDescriptor = typeDescriptor.CollectionPropertyDescriptors[i]; await this.SaveCollection(collectionPropertyDescriptor, entity, typeDescriptor, @async); } }
ComplexObjectModel GenComplexObjectModel(ComplexPropertyDescriptor navigationDescriptor, NavigationNode navigationNode, QueryModel queryModel) { TypeDescriptor navigationTypeDescriptor = EntityTypeContainer.GetDescriptor(navigationDescriptor.PropertyType); DbTable dbTable = navigationTypeDescriptor.Table; DbTableExpression tableExp = new DbTableExpression(dbTable); string alias = queryModel.GenerateUniqueTableAlias(dbTable.Name); DbTableSegment joinTableSeg = new DbTableSegment(tableExp, alias, queryModel.FromTable.Table.Lock); DbTable aliasTable = new DbTable(alias); ComplexObjectModel navigationObjectModel = navigationTypeDescriptor.GenObjectModel(aliasTable); navigationObjectModel.NullChecking = navigationObjectModel.PrimaryKey; PrimitivePropertyDescriptor foreignKeyPropertyDescriptor = navigationDescriptor.ForeignKeyProperty; DbExpression foreignKeyColumn = this.GetPrimitiveMember(foreignKeyPropertyDescriptor.Property); DbExpression joinCondition = DbExpression.Equal(foreignKeyColumn, navigationObjectModel.PrimaryKey); DbJoinTableExpression joinTableExp = new DbJoinTableExpression(foreignKeyPropertyDescriptor.IsNullable ? DbJoinType.LeftJoin : DbJoinType.InnerJoin, joinTableSeg, joinCondition); this.DependentTable.JoinTables.Add(joinTableExp); navigationObjectModel.DependentTable = joinTableExp; DbExpression condition = this.ParseCondition(navigationNode.Condition, navigationObjectModel, queryModel.ScopeTables); //AndWhere的条件放到join条件里去 joinTableExp.AppendCondition(condition); navigationObjectModel.Filter = this.ParseCondition(navigationNode.Filter, navigationObjectModel, queryModel.ScopeTables); //queryModel.Filters.Add(navigationObjectModel.Filter); return(navigationObjectModel); }
async Task SaveOneToOne(ComplexPropertyDescriptor navPropertyDescriptor, object owner, TypeDescriptor ownerTypeDescriptor, bool @async) { /* * 1:1 * T <1:1> TOther * T.TOther <--> TOther.T * T.Id <--> TOther.Id */ //owner is T //navPropertyDescriptor is T.TOther //TypeDescriptor of T.TOther TypeDescriptor navTypeDescriptor = EntityTypeContainer.GetDescriptor(navPropertyDescriptor.PropertyType); //TOther.T ComplexPropertyDescriptor TOtherDotT = navTypeDescriptor.ComplexPropertyDescriptors.Where(a => a.PropertyType == ownerTypeDescriptor.Definition.Type).FirstOrDefault(); bool isOneToOne = TOtherDotT != null; if (!isOneToOne) { return; } //instance of T.TOther object navValue = navPropertyDescriptor.GetValue(owner); if (navValue == null) { return; } //T.Id PrimitivePropertyDescriptor foreignKeyProperty = navPropertyDescriptor.ForeignKeyProperty; if (foreignKeyProperty.IsAutoIncrement || foreignKeyProperty.HasSequence()) { //value of T.Id object foreignKeyValue = foreignKeyProperty.GetValue(owner); //T.TOther.Id = T.Id TOtherDotT.ForeignKeyProperty.SetValue(navValue, foreignKeyValue); } MethodInfo saveMethod = GetSaveMethod(navPropertyDescriptor.PropertyType); //DbContext.Save(navValue, ownerTypeDescriptor, @async); Task task = (Task)saveMethod.Invoke(this, navValue, ownerTypeDescriptor, @async); await task; }
ComplexObjectModel GenCollectionElementObjectModel(TypeDescriptor elementTypeDescriptor, NavigationNode navigationNode, QueryModel queryModel) { DbTable dbTable = elementTypeDescriptor.Table; DbTableExpression tableExp = new DbTableExpression(dbTable); string alias = queryModel.GenerateUniqueTableAlias(dbTable.Name); DbTableSegment joinTableSeg = new DbTableSegment(tableExp, alias, queryModel.FromTable.Table.Lock); DbTable aliasTable = new DbTable(alias); ComplexObjectModel elementObjectModel = elementTypeDescriptor.GenObjectModel(aliasTable); elementObjectModel.NullChecking = elementObjectModel.PrimaryKey; ComplexPropertyDescriptor navigationDescriptor = elementTypeDescriptor.ComplexPropertyDescriptors.Where(a => a.PropertyType == this.ObjectType).FirstOrDefault(); if (navigationDescriptor == null) { throw new ChloeException($"You have to define a navigation property which type is '{this.ObjectType.FullName}' on class '{elementTypeDescriptor.Definition.Type.FullName}'."); } DbExpression elementForeignKeyColumn = elementObjectModel.GetPrimitiveMember(navigationDescriptor.ForeignKeyProperty.Property); DbExpression joinCondition = DbExpression.Equal(this.PrimaryKey, elementForeignKeyColumn); DbJoinTableExpression joinTableExp = new DbJoinTableExpression(DbJoinType.LeftJoin, joinTableSeg, joinCondition); this.DependentTable.JoinTables.Add(joinTableExp); elementObjectModel.DependentTable = joinTableExp; var condition = this.ParseCondition(navigationNode.Condition, elementObjectModel, queryModel.ScopeTables); //AndWhere的条件放到join条件里去 joinTableExp.AppendCondition(condition); elementObjectModel.Filter = this.ParseCondition(navigationNode.Filter, elementObjectModel, queryModel.ScopeTables); bool orderByPrimaryKeyExists = queryModel.Orderings.Where(a => a.Expression == this.PrimaryKey).Any(); if (!orderByPrimaryKeyExists) { //结果集分组 DbOrdering ordering = new DbOrdering(this.PrimaryKey, DbOrderType.Asc); queryModel.Orderings.Add(ordering); } //queryModel.Filters.Add(elementObjectModel.Filter); return(elementObjectModel); }
async Task SaveCollection(CollectionPropertyDescriptor collectionPropertyDescriptor, object owner, TypeDescriptor ownerTypeDescriptor, bool @async) { PrimitivePropertyDescriptor ownerKeyPropertyDescriptor = ownerTypeDescriptor.PrimaryKeys.FirstOrDefault(); if (ownerKeyPropertyDescriptor == null) { return; } //T.Elements IList elementList = collectionPropertyDescriptor.GetValue(owner) as IList; if (elementList == null || elementList.Count == 0) { return; } TypeDescriptor elementTypeDescriptor = EntityTypeContainer.GetDescriptor(collectionPropertyDescriptor.ElementType); //Element.T ComplexPropertyDescriptor elementDotT = elementTypeDescriptor.ComplexPropertyDescriptors.Where(a => a.PropertyType == ownerTypeDescriptor.Definition.Type).FirstOrDefault(); object ownerKeyValue = ownerKeyPropertyDescriptor.GetValue(owner); MethodInfo saveMethod = GetSaveMethod(collectionPropertyDescriptor.ElementType); for (int i = 0; i < elementList.Count; i++) { object element = elementList[i]; if (element == null) { continue; } //element.ForeignKey = T.Id elementDotT.ForeignKeyProperty.SetValue(element, ownerKeyValue); //DbContext.Save(element, ownerTypeDescriptor, @async); Task task = (Task)saveMethod.Invoke(this, element, ownerTypeDescriptor, @async); await task; } }
bool CanMoveSelectedRowsToGroup(DragDropManagerBase sourceManager, GroupInfo[] groupInfos, DependencyObject hitElement) { if(GetRowElement(hitElement) == null) return false; foreach(object obj in sourceManager.DraggingRows) { if(!ItemsSource.Contains(obj)) return true; foreach(GroupInfo groupInfo in groupInfos) { object value; if(groupInfo.FieldName.Contains(".")) { ComplexPropertyDescriptor complexDescr = new ComplexPropertyDescriptor(obj, groupInfo.FieldName); value = complexDescr.GetValue(obj); } else value = TypeDescriptor.GetProperties(obj)[groupInfo.FieldName].GetValue(obj); if(!object.Equals(value, groupInfo.Value)) return true; } } return false; }