/// <summary> /// Removes a whole tree under input, this is the 'inverse' of Clone but this is too slow for a whole Canton... /// </summary> public void Remove(IPocoBase input, IAgrideaService service) { if (input == null) { return; } var pocoType = ObjectContext.GetObjectType(input.GetType()); var pocoTypeName = pocoType.Name; if (excludedPocos_.Contains(pocoType)) { return; } if (input.GetType().IsReferenceEntity()) { return; } if (deleted_.ContainsKey(input)) { return; } Log.Verbose("CloningHelper.Remove ({0})", input); deleted_.Add(input, true); foreach (var referenceProperty in input.GetType().GetReferenceProperties()) { var reference = referenceProperty.GetValue(input) as IPocoBase; if (reference == null) { continue; } Remove(reference, service); } foreach (var collectionProperty in input.GetType().GetCollectionProperties()) { var inputCollection = collectionProperty.GetValue(input) as IList; if (inputCollection.Count == 0) { continue; } foreach (IPocoBase inputItem in new ArrayList(inputCollection)) //to avoid collection change during iteration { Remove(inputItem, service); } } service.RemoveItem(input); //Must be at the end otherwise all relationships are cleared }
private IQueryable <TPoco> GetQueryForDiscriminantProperties <TPoco>(IQueryable <TPoco> items, IPocoBase item) where TPoco : class, IPocoBase { var type = typeof(TPoco); Asserts <InvalidOperationException> .IsTrue(item.HasDiscriminant(), String.Format("Poco {0} has no discriminant property", type.Name)); var discriminantProperties = type.GetRecursiveDiscriminantProperties(); var parameterExpression = Expression.Parameter(type, "item"); foreach (var discriminant in discriminantProperties) { Expression memberExpression = parameterExpression; object value = null; type = typeof(TPoco); var curItem = item; foreach (var propertyName in discriminant.Split('.')) { var pi = type.GetProperty(propertyName); value = pi.GetValue(curItem, null); memberExpression = Expression.Property(memberExpression, pi); type = pi.PropertyType; if (pi.PropertyType.IsReference()) { curItem = value as PocoBase; } } items = items.Where(Expression.Lambda <Func <TPoco, bool> >( Expression.Equal(memberExpression, Expression.Constant(value)), new[] { parameterExpression })); } return(items); }
/// <summary> /// Clones a whole tree under input. /// ReferenceEntity are copied by ref, all others by values /// Dicrimimants are changed to maintain UC, except when pragmatic condition is met /// </summary> public IPocoBase Clone(IPocoBase input, IAgrideaService service) { if (input == null) { return(null); } var pocoType = ObjectContext.GetObjectType(input.GetType()); var pocoTypeName = pocoType.Name; if (excludedPocos_.Contains(pocoType)) { return(null); } if (input.GetType().IsReferenceEntity()) { return(input); } if (clones_.ContainsKey(input)) { return(clones_[input]); } Log.Verbose("CloningHelper.Clone ({0})", input); IPocoBase result = Activator.CreateInstance(input.GetType()) as IPocoBase; result.CreatedBy = service.UserName; result.CreationDate = DateTime.Now; clones_.Add(input, result); var discriminantProperties = input.GetType().GetPrimitiveDiscriminantProperties().ToList(); var generateNewDiscriminant = discriminantProperties.All(m => m.IsPrimitive() || discriminantProperties.Count() == 1); foreach (var primitiveProperty in input.GetType().GetPrimitiveProperties()) { var val = primitiveProperty.GetValue(input); if (primitiveProperty.IsDiscriminant()) { //bug for BankAccount Ccp Number and Iban => discriminant but potentially null val = val is string && string.IsNullOrWhiteSpace(val.ToString()) ? "-" : val; val = generateNewDiscriminant ? NextDicriminantValue(primitiveProperty, val) : val; } primitiveProperty.SetValue(result, val); } foreach (var referenceProperty in input.GetType().GetReferenceProperties()) { var reference = referenceProperty.GetValue(input) as IPocoBase; if (reference == null) { continue; } referenceProperty.SetValue(result, Clone(reference, service)); } foreach (var collectionProperty in input.GetType().GetCollectionProperties()) { var inputCollection = collectionProperty.GetValue(input) as IList; if (inputCollection.Count == 0) { continue; } IList inputCollectionClone = Activator.CreateInstance(typeof(List <>).MakeGenericType(collectionProperty.PropertyType.GenericTypeArguments[0])) as IList; collectionProperty.SetValue(result, inputCollectionClone); foreach (IPocoBase inputItem in inputCollection) { inputCollectionClone.Add(Clone(inputItem, service)); } } return(result); }