private static void SetChanges(this DbContext context, ITrackable item, EntityState state, ObjectVisitationHelper visitationHelper, ITrackable parent = null, string propertyName = null) { // Set state for child collections foreach (var navProp in item.GetNavigationProperties()) { string propName = navProp.Property.Name; // Apply changes to 1-1 and M-1 properties foreach (var refProp in navProp.AsReferenceProperty()) { ITrackable trackableReference = refProp.EntityReference; if (visitationHelper.IsVisited(trackableReference)) { continue; } context.ApplyChanges(trackableReference, item, visitationHelper, propName); if (context.IsRelatedProperty(item.GetType(), propName, RelationshipType.OneToOne)) { context.SetChanges(trackableReference, state, visitationHelper, item, propName); } } // Apply changes to 1-M and M-M properties foreach (var colProp in navProp.AsCollectionProperty()) { foreach (ITrackable trackableChild in colProp.EntityCollection.Reverse()) { // Prevent endless recursion if (visitationHelper.TryVisit(trackableChild)) { // TRICKY: we have just visited the item // As a side effect, ApplyChanges will never be called for it. context.SetChanges(trackableChild, state, visitationHelper, item, propName); } } } } // If M-M child, set relationship for deleted items if (state == EntityState.Deleted && parent != null && propertyName != null && (context.IsRelatedProperty(parent.GetType(), propertyName, RelationshipType.ManyToMany))) { context.Entry(item).State = item.TrackingState == TrackingState.Modified ? EntityState.Modified : EntityState.Unchanged; context.SetRelationshipState(item, parent, propertyName, EntityState.Deleted); return; } // Set entity state context.Entry(item).State = state; }
private void FixUpParentReference(ITrackable child, ITrackable parent, bool isTracking) { foreach (var refProp in child.GetNavigationProperties() .OfReferenceType() #if SILVERLIGHT || NET40 .Where(rp => rp.Property.PropertyType.IsAssignableFrom(parent.GetType())) #else .Where(rp => rp.Property.PropertyType.GetTypeInfo().IsAssignableFrom(parent.GetType().GetTypeInfo())) #endif .Where(rp => !ReferenceEquals(rp.EntityReference, parent))) { Tracking = false; refProp.Property.SetValue(child, parent, null); Tracking = isTracking; } }
/// <summary> /// Get reference property change tracker. /// </summary> /// <param name="item">ITrackable object</param> /// <param name="propertyName">Reference property name</param> /// <returns>Reference property change tracker</returns> public static ITrackingCollection GetRefPropertyChangeTracker(this ITrackable item, string propertyName) { var resolver = item as IRefPropertyChangeTrackerResolver; if (resolver != null) { return(resolver.GetRefPropertyChangeTracker(propertyName)); } var property = GetChangeTrackingProperty(item.GetType(), propertyName); if (property == null) { return(null); } return(property.GetValue(item, null) as ITrackingCollection); }
public IEnumerable <EntityNavigationProperty> GetNavigationProperties() { foreach (var prop in Entity.GetType().GetProperties()) { // 1-1 and M-1 properties if (typeof(ITrackable).IsAssignableFrom(prop.PropertyType)) { var trackableRef = prop.GetValue(Entity, null) as ITrackable; yield return(new EntityReferenceProperty(prop, trackableRef)); } // 1-M and M-M properties if (typeof(IEnumerable <ITrackable>).IsAssignableFrom(prop.PropertyType)) { var items = prop.GetValue(Entity, null) as IEnumerable <ITrackable>; yield return(new EntityCollectionProperty(prop, items)); } } }
static void Main(string[] args) { logger.LogInfo("Log initialized"); var lines = File.ReadAllLines(csvPath); logger.LogInfo($"Lines: {lines[0]}"); ITrackable tacoBell1 = null; ITrackable tacoBell2 = null; double finalDistance = 0; double testDistance = 0; var geo1 = new GeoCoordinate(); var geo2 = new GeoCoordinate(); // Transforms each line (string) to an ITrackable object and saves it to the locations array var locations = lines.Select(TacoParser.Parse).ToArray(); for (int i = 0; i < locations.Length; i++) { geo1.Latitude = locations[i].Location.Latitude; geo1.Longitude = locations[i].Location.Longitude; for (int j = 1; j < locations.Length; j++) { geo2.Latitude = locations[j].Location.Latitude; geo2.Longitude = locations[j].Location.Longitude; testDistance = geo1.GetDistanceTo(geo2); if (finalDistance < testDistance) { finalDistance = testDistance; tacoBell1 = locations[i]; tacoBell2 = locations[j]; } } } //logger.LogInfo($"{tacoBell1.Name} and {tacoBell2.Name}"); Console.WriteLine($"The 2 furthest {tacoBell1.GetType().Name}'s are {tacoBell1.Name} and {tacoBell2.Name}."); Console.WriteLine($"The total distance is {Math.Round((finalDistance * metersToMiles), 2)} miles."); }
public void Delete(ITrackable obj) { try { if (obj == null) { return; } // var c = conText.ObjectStateManager.GetObjectStateEntry(obj); var ds = conText.Set(obj.GetType()); ds.Attach(obj); //c.EntitySet.Name ds.Remove(obj); conText.SaveChanges(); //obj.AcceptChanges(); } catch (Exception ex) { throw ex; } }
private void FixUpParentReference(ITrackable child, ITrackable parent, bool isTracking) { foreach (var refProp in child.GetNavigationProperties() .OfReferenceType() .Where(rp => PortableReflectionHelper.Instance.IsAssignable(rp.Property.PropertyType, parent.GetType())) .Where(rp => !ReferenceEquals(rp.EntityReference, parent))) { Tracking = false; refProp.Property.SetValue(child, parent, null); Tracking = isTracking; } }
public static void SetDefaultTracker(this ITrackable trackable) { trackable.Tracker = TrackerResolver.CreateDefaultTracker(trackable.GetType()); }
private static void ApplyChanges(this DbContext context, ITrackable item, ITrackable parent, ObjectVisitationHelper visitationHelper, string propertyName, TrackingState?state = null) { // Prevent endless recursion // if (!Exists(context, item)) return; if (!visitationHelper.TryVisit(item)) { return; } // Check for null args if (context == null) { throw new ArgumentNullException("context"); } if (item == null) { throw new ArgumentNullException("item"); } // If M-M child, set relationship for added or deleted items if (parent != null && propertyName != null && (context.IsRelatedProperty(parent.GetType(), propertyName, RelationshipType.ManyToMany))) { // If parent is added set tracking state to match var trackingState = item.TrackingState; if (parent.TrackingState == TrackingState.Added) { trackingState = parent.TrackingState; } // If tracking state is added set entity to unchanged, // then add or delete relation. if (trackingState == TrackingState.Added || trackingState == TrackingState.Deleted) { context.Entry(item).State = item.TrackingState == TrackingState.Modified ? EntityState.Modified : EntityState.Unchanged; context.SetRelationshipState(item, parent, propertyName, trackingState.ToEntityState()); } else { // Set entity state for modified or unchanged if (item.TrackingState == TrackingState.Modified) { context.Entry(item).State = EntityState.Modified; } else if (item.TrackingState == TrackingState.Unchanged) { context.Entry(item).State = EntityState.Unchanged; } } // Set state for child collections context.ApplyChangesOnProperties(item, visitationHelper); return; } // Exit if parent is added or deleted, // and it's not a M-1 relation if (parent != null && (parent.TrackingState == TrackingState.Added || parent.TrackingState == TrackingState.Deleted) && !context.IsRelatedProperty(parent.GetType(), propertyName, RelationshipType.ManyToOne)) { context.ApplyChangesOnProperties(item, visitationHelper); return; } // If it is a M-1 relation and item state is deleted, // set to unchanged and exit if (parent != null && (context.IsRelatedProperty(parent.GetType(), propertyName, RelationshipType.ManyToOne) && item.TrackingState == TrackingState.Deleted)) { try { context.Entry(item).State = EntityState.Unchanged; } catch (InvalidOperationException invalidOpEx) { throw new InvalidOperationException(Constants.ExceptionMessages.DeletedWithAddedChildren, invalidOpEx); } return; } // Set state to Added on parent only if (item.TrackingState == TrackingState.Added && (state == null || state == TrackingState.Added)) { context.Entry(item).State = EntityState.Added; context.ApplyChangesOnProperties(item, visitationHelper); return; } // Set state to Deleted on children and parent if (item.TrackingState == TrackingState.Deleted && (state == null || state == TrackingState.Deleted)) { context.SetChanges(item, EntityState.Unchanged, visitationHelper.Clone()); // Clone to avoid interference context.SetChanges(item, EntityState.Deleted, visitationHelper); return; } // Set entity state if (state == null || state == TrackingState.Unchanged || state == TrackingState.Modified || (state == TrackingState.Added && item.TrackingState != TrackingState.Deleted)) { // Set added state for reference or child properties context.ApplyChangesOnProperties(item, visitationHelper.Clone(), TrackingState.Added); // Clone to avoid interference // Set modified properties if (item.TrackingState == TrackingState.Modified && (state == null || state == TrackingState.Modified) && item.ModifiedProperties != null && item.ModifiedProperties.Count > 0) { // Mark modified properties context.Entry(item).State = item.TrackingState.ToEntityState(); //EntityState.Unchanged; foreach (var property in item.ModifiedProperties) { context.Entry(item).Property(property).IsModified = true; } } else { try { context.Entry(item).State = item.TrackingState.ToEntityState(); } catch (Exception) { if (item.TrackingState != TrackingState.Unchanged) { throw; } } } // Set other state for reference or child properties context.ApplyChangesOnProperties(item, visitationHelper.Clone(), TrackingState.Unchanged); // Clone to avoid interference context.ApplyChangesOnProperties(item, visitationHelper.Clone(), TrackingState.Modified); // Clone to avoid interference context.ApplyChangesOnProperties(item, visitationHelper, TrackingState.Deleted); } }
private static void SetEntityProperties(this ITrackable targetItem, ITrackable sourceItem, ITrackingCollection changeTracker) { // List of 'prop.SetValue' actions var actions = new List <Action>(); // Iterate simple properties #if SILVERLIGHT || NET40 foreach (var prop in targetItem.GetType().GetProperties().Where(p => p.CanWrite) #else foreach (var prop in targetItem.GetType().GetTypeInfo().DeclaredProperties .Where(p => p.CanWrite && !p.GetMethod.IsPrivate) #endif .Except(targetItem.GetNavigationProperties(false).Select(np => np.Property))) { // Skip tracking properties if (prop.Name == Constants.TrackingProperties.TrackingState || prop.Name == Constants.TrackingProperties.ModifiedProperties) { continue; } // Get source item prop value object sourceValue = prop.GetValue(sourceItem, null); object targetValue = prop.GetValue(targetItem, null); // Continue if source is null or source and target equal if (sourceValue == null || sourceValue.Equals(targetValue)) { continue; } // Deferred 'SetValue' actions.Add(() => prop.SetValue(targetItem, sourceValue, null)); } // Iterate entity reference properties (skip collections) foreach (var refProp in targetItem .GetNavigationProperties(false) .OfReferenceType() .Where(np => np.Property.CanWrite)) { ITrackable targetValue = refProp.EntityReference; // Skip non-null trackable if (targetValue != null) { continue; } ITrackable sourceValue = sourceItem.GetEntityReferenceProperty(refProp.Property).EntityReference; // Continue if source is null if (sourceValue == null) { continue; } // Deferred 'SetValue' actions.Add(() => refProp.Property.SetValue(targetItem, sourceValue, null)); } // Nothing to do? if (!actions.Any()) { return; } // Turn off change-tracking bool isTracking = changeTracker.Tracking; changeTracker.Tracking = false; // Set target item prop value foreach (var action in actions) { action(); } // Reset change-tracking changeTracker.Tracking = isTracking; }
public void Start(bool deleteRecordAfterMigration, int startAt, int stopAfter, int docsImported) { var docNumber = startAt; try { var trackerDocuments = _mongoDatabase.GetCollection("TrackerData"); //var sqlPersister = new PersistToSQLServer(_sqlConnectionString, new ConsoleLogger()); foreach (var trackerDocument in trackerDocuments.FindAll().Skip(startAt)) { Debug.Write(trackerDocument); TrackerData trackerData = null; ITrackable tracker = null; string trackerTypeName = null; DateTime? timeSlot = null; foreach (var element in trackerDocument.Elements) { if (element.Name == "TypeName") { trackerTypeName = element.Value.ToString(); } } if (trackerTypeName != null) { trackerData = new TrackerData(trackerTypeName); foreach (var element in trackerDocument.Elements) { switch (element.Name) { case "Name": trackerData.Name = element.Value.ToString(); break; case "KeyFilter": trackerData.KeyFilter = element.Value.ToString(); break; case "TimeSlot": timeSlot = Convert.ToDateTime(element.Value.ToString()); break; //case "SearchFilters": // var filters = // element.Value.AsBsonArray.Select(p => p.AsString).ToArray(); // for (var i = 0; i < filters.Length; i++) // { // filters[i] = filters[i].Split(new [] {",,"}, StringSplitOptions.None).OrderBy(f => f).Aggregate((x, z) => string.Concat(x, ",,", z));//this is to fix a bug that was caused by the missing sort in the previous version. // } // trakerData.SearchFilters = filters; // break; case "Measurement": var mesurementDoc = (BsonDocument)element.Value; trackerData.Measurement = new Measure(); trackerData.Measurement.NamedMetrics = new ConcurrentDictionary <string, long>(); foreach (var measure in mesurementDoc.Elements) { //switch (measure.Name) //{ // case "_Total": // trakerData.Measurement._Total = Convert.ToInt32(measure.Value.ToString()); // break; // case "_Occurrence": // trakerData.Measurement._Occurrence = // Convert.ToInt32(measure.Value.ToString()); // break; // case "_Min": // trakerData.Measurement._Min = Convert.ToInt32(measure.Value.ToString()); // break; // case "_Max": // trakerData.Measurement._Max = Convert.ToInt32(measure.Value.ToString()); // break; // default: var val = Convert.ToInt32(measure.Value); trackerData.Measurement.NamedMetrics.AddOrUpdate(measure.Name, val, (i, t) => t + val); // break; //} } break; } } tracker = TrackerBuilder.CreateTrackerFromTypeName(trackerTypeName, trackerData.Name); object filter = null; if (!string.IsNullOrWhiteSpace(trackerData.KeyFilter)) { filter = TrackerBuilder.CreateFilterObject(trackerData.KeyFilter); } var grapheneContainer = typeof(Container <>).MakeGenericType(tracker.GetType()); var grapheneContainerInstance = Activator.CreateInstance(grapheneContainer); // var grapheneSetTrackerType = // grapheneContainer.GetMethod("SetTrackerType", BindingFlags.Instance | BindingFlags.NonPublic); // grapheneSetTrackerType.Invoke(grapheneContainerInstance, new[] { tracker }); var grapheneIncrement = grapheneContainer.GetMethod("Increment", BindingFlags.Instance | BindingFlags.NonPublic, Type.DefaultBinder, new[] { typeof(ITrackable), typeof(Resolution), typeof(DateTime), typeof(string), typeof(long), typeof(object) }, null); foreach (var metric in trackerData.Measurement.NamedMetrics) { grapheneIncrement.Invoke(grapheneContainerInstance, new[] { tracker, Resolution.Day, timeSlot, metric.Key, metric.Value, filter }); } if (deleteRecordAfterMigration) { trackerDocuments.Remove(Query <TrackerData> .EQ(td => td._id, trackerData._id)); } if (_logger != null) { _logger.Info(string.Format("Migrated Document with ID:{0}, Number{1}", trackerData._id, docNumber)); } docNumber++; docsImported++; if (_stopCalled || (stopAfter != -1 && docsImported >= stopAfter)) { break; } } } } catch (Exception exception) { _logger.Error(exception.Message, exception); if (exception is MongoDB.Driver.MongoQueryException && exception.Message == "Cursor not found.")//todo: find out the exception type. { Start(deleteRecordAfterMigration, docNumber, stopAfter, docsImported); } } }