/// <summary> /// Gets a list of groups surrounding the specified geopoint of the specified GroupTypeid /// If geofenceGroupTypeId is specified, the list of GeoFence groups will be returned with the groups as child groups of that geofence group. /// </summary> /// <param name="groupTypeId">The group type identifier.</param> /// <param name="geoPoint">The geo point.</param> /// <param name="sortByDistance">if set to <c>true</c> [sort by distance].</param> /// <param name="maxDistanceMiles">The maximum distance miles.</param> /// <param name="geofenceGroupTypeId">The geofence group type identifier.</param> /// <param name="queryOptions">The query options.</param> /// <returns></returns> private IQueryable GetByGeoPoint( int groupTypeId, DbGeography geoPoint, bool? sortByDistance, double? maxDistanceMiles, int? geofenceGroupTypeId, System.Web.Http.OData.Query.ODataQueryOptions<Group> queryOptions ) { var rockContext = (RockContext)Service.Context; IEnumerable<Group> resultGroups = new List<Group>(); if ( geoPoint != null ) { if ( geofenceGroupTypeId.HasValue && geofenceGroupTypeId.Value > 0 ) { var fenceGroups = new List<Group>(); // Find all the groupLocation records ( belonging to groups of the "geofenceGroupType" ) // where the geofence surrounds the location var groupLocationService = new GroupLocationService( rockContext ); foreach ( var fenceGroupLocation in groupLocationService .Queryable( "Group,Location" ).AsNoTracking() .Where( gl => gl.Group.GroupTypeId == geofenceGroupTypeId && gl.Location.GeoFence != null && geoPoint.Intersects( gl.Location.GeoFence ) ) .ToList() ) { var fenceGroup = fenceGroups.FirstOrDefault( g => g.Id == fenceGroupLocation.GroupId ); if ( fenceGroup == null ) { fenceGroup = fenceGroupLocation.Group; fenceGroups.Add( fenceGroup ); } fenceGroupLocation.Group = null; // Find all the group groupLocation records ( with group of the "groupTypeId" ) that have a location // within the fence foreach ( var group in Service .Queryable( "Schedule,GroupLocations.Location" ).AsNoTracking() .Where( g => g.GroupTypeId == groupTypeId && g.GroupLocations.Any( gl => gl.Location.GeoPoint != null && gl.Location.GeoPoint.Intersects( fenceGroupLocation.Location.GeoFence ) ) ) ) { // Remove any other group locations that do not belong to fence foreach ( var gl in group.GroupLocations.ToList() ) { if ( gl.Location.GeoPoint == null || !gl.Location.GeoPoint.Intersects( fenceGroupLocation.Location.GeoFence ) ) { group.GroupLocations.Remove( gl ); } } fenceGroup.Groups.Add( group ); } } resultGroups = fenceGroups; } else { // if a geoFence is not specified, just get all groups of this group type resultGroups = Service.Queryable( "Schedule,GroupLocations.Location" ).AsNoTracking().Where( a => a.GroupTypeId == groupTypeId ).Include( a => a.GroupLocations ).ToList(); } } // calculate the distance of each of the groups locations from the specified geoFence foreach ( var group in resultGroups ) { foreach ( var gl in group.GroupLocations ) { // Calculate distance if ( gl.Location.GeoPoint != null ) { double meters = gl.Location.GeoPoint.Distance( geoPoint ) ?? 0.0D; gl.Location.SetDistance( meters * Location.MilesPerMeter ); } } } // remove groups that don't have a GeoPoint resultGroups = resultGroups.Where( a => a.GroupLocations.Any( x => x.Location.GeoPoint != null ) ); // remove groups that don't have a location within the specified radius if ( maxDistanceMiles.HasValue ) { resultGroups = resultGroups.Where( a => a.GroupLocations.Any( x => x.Location.Distance <= maxDistanceMiles.Value ) ); } var querySettings = new System.Web.Http.OData.Query.ODataQuerySettings(); if ( sortByDistance.HasValue && sortByDistance.Value ) { resultGroups = resultGroups.OrderBy( a => a.GroupLocations.FirstOrDefault() != null ? a.GroupLocations.FirstOrDefault().Location.Distance : int.MaxValue ).ToList(); // if we are sorting by distance, tell OData not to re-sort them by Id querySettings.EnsureStableOrdering = false; } // manually apply any OData parameters to the InMemory Query var qryResults = queryOptions.ApplyTo( resultGroups.AsQueryable(), querySettings ); return qryResults.AsQueryable(); }
public IEnumerable<Customer> CustomersWithOptions(System.Web.Http.OData.Query.ODataQueryOptions queryOptions) { // Process the queryOptions manually; allows extra processing before and after the query is performed var queryable = _repository.Customers; var newQueryable = queryOptions.ApplyTo(queryable).Cast<Customer>(); newQueryable = newQueryable.Where(c => c.Country == "Germany"); var list = newQueryable.ToList(); // do something else to the list... return list; }