public static TrackedIdentities FromArray(TrackedPrimaryKey[][] array) { TrackedIdentities result = new TrackedIdentities(); foreach (var entry in array) { result.Add(TrackedIdentity.FromArray(entry)); } return(result); }
private void Track(DbContext db, object value) { TrackingDictionary dict = new TrackingDictionary(); bool trackThisInstance = typeof(ITrackable).IsAssignableFrom(value.GetType()); foreach (var property in value.GetType().GetProperties()) { if (property.PropertyType.IsGenericType && typeof(IEnumerable).IsAssignableFrom(property.PropertyType)) { var elementType = property.PropertyType.GetElementTypeIfCollection(); if (trackThisInstance) //track related entities of this instance { TrackedIdentities entities = new TrackedIdentities(); Type entityType = elementType.TrackAs(); if (entityType == null) { var entityTypeCandidates = AutoMapper.Mapper.GetAllTypeMaps().Where(x => x.SourceType == elementType).Select(x => x.DestinationType) .Union(AutoMapper.Mapper.GetAllTypeMaps().Where(x => x.DestinationType == elementType).Select(x => x.SourceType)).ToList(); if (entityTypeCandidates.Count == 0) { throw new CatFlapException("Found no entity type to track against for type " + elementType.FullName); } else if (entityTypeCandidates.Count > 1) { throw new CatFlapException("Ambiguous choice of entity type to track against for type " + elementType.FullName + ". Add a [TrackAs] attribute to the class definition to specify which of the mapped types to track against."); } else { entityType = entityTypeCandidates.Single(); } } var keyNames = GetKeyNames(db, entityType); var collection = (IEnumerable)property.GetValue(value); var propertyNameTransforms = GetPropertyNameTransforms(elementType, entityType); foreach (var item in collection) { TrackedIdentity entity = new TrackedIdentity(); foreach (var key in keyNames) { entity.Add(new TrackedPrimaryKey() { PropertyName = key, Value = elementType.GetProperty(propertyNameTransforms[key]).GetValue(item) }); } entities.Add(entity); } dict.Add(property.Name, entities); } if (typeof(ITrackable).IsAssignableFrom(elementType)) { IEnumerable items = (IEnumerable)property.GetValue(value); foreach (var item in items) { Track(db, item); //be all recursive and shit } } } else if (typeof(ITrackable).IsAssignableFrom(property.PropertyType)) { Track(db, property.GetValue(value)); //be all recursive and shit } } if (trackThisInstance) //track related entities of this instance { typeof(ITrackable).GetProperty("TrackingToken").SetValue(value, dict.ToBase64()); } }