WeatherInformation WP8: database access improvements
authorgu.martinm@gmail.com <gu.martinm@gmail.com>
Fri, 15 Aug 2014 10:44:20 +0000 (12:44 +0200)
committergu.martinm@gmail.com <gu.martinm@gmail.com>
Fri, 15 Aug 2014 10:44:20 +0000 (12:44 +0200)
WindowsPhone/WeatherInformation/WeatherInformation/App.xaml.cs
WindowsPhone/WeatherInformation/WeatherInformation/MainPage.xaml.cs
WindowsPhone/WeatherInformation/WeatherInformation/MapPage.xaml.cs

index dfda732..592dcc6 100644 (file)
@@ -31,9 +31,6 @@ namespace WeatherInformation
         // Declare a private variable to store application state.
         private WeatherData _remoteWeatherData;
 
-        // Declare an event for when the application data changes.
-        public event EventHandler ApplicationDataObjectChanged;
-
         // Declare a public property to access the application data variable.
         public WeatherData ApplicationDataObject
         {
@@ -43,21 +40,10 @@ namespace WeatherInformation
                 if (value != _remoteWeatherData)
                 {
                     _remoteWeatherData = value;
-                    OnApplicationDataObjectChanged(EventArgs.Empty);
                 }
             }
         }
 
-        // Create a method to raise the ApplicationDataObjectChanged event.
-        protected void OnApplicationDataObjectChanged(EventArgs e)
-        {
-            EventHandler handler = ApplicationDataObjectChanged;
-            if (handler != null)
-            {
-                handler(this, e);
-            }
-        }
-
         /// <summary>
         /// Proporcionar acceso sencillo al marco raíz de la aplicación telefónica.
         /// </summary>
index 9a9658c..b133b16 100644 (file)
@@ -22,9 +22,6 @@ namespace WeatherInformation
     {
         private MainViewModel _mainViewModel;
         private bool _isNewPageInstance = false;
-        // Data context for the local database
-        private LocationDataContext _locationDB;
-        private Location _locationItem;
 
         // Constructor
         public MainPage()
@@ -33,17 +30,6 @@ namespace WeatherInformation
 
             _isNewPageInstance = true;
 
-            // Set the event handler for when the application data object changes.
-            // TODO: doing this, when is the GC going to release this object? I do not think it is going to be able... This is weird...
-            // Shouldn't I release this even handler when the MainPage is not used anymore. In my case is not a big problem because
-            // the MainPage should be always active (it is the "mainpage") but if this was not the mainpage... Would the GC be able
-            // to release this object when the page is not active... I DO NOT THINK SO...
-            (Application.Current as WeatherInformation.App).ApplicationDataObjectChanged +=
-                          new EventHandler(MainPage_ApplicationDataObjectChanged);
-
-            // Connect to the database and instantiate data context.
-            _locationDB = new LocationDataContext(LocationDataContext.DBConnectionString);
-
             // Código de ejemplo para traducir ApplicationBar
             //BuildLocalizedApplicationBar();
         }
@@ -69,26 +55,18 @@ namespace WeatherInformation
             // and it has remained in memory, this value will continue to be false.
             _isNewPageInstance = false;
 
-            _locationItem = _locationDB.Locations.Where(location => location.IsSelected).FirstOrDefault();
-
             UpdateApplicationDataUI();
         }
 
-        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
+        async private void UpdateApplicationDataUI()
         {
-            // Call the base method.
-            base.OnNavigatedFrom(e);
-
-            // Save changes to the database.
-            // TODO: How does DataContext work? How does it know what data was modified? Is it wasting memory? :(
-            _locationDB.SubmitChanges();
-
-            // No calling _locationDB.Dispose? :/
-        }
+            Location locationItem = null;
+            using (var db = new LocationDataContext(LocationDataContext.DBConnectionString))
+            {
+                locationItem = db.Locations.Where(location => location.IsSelected).FirstOrDefault();
+            }
 
-        private void UpdateApplicationDataUI()
-        {
-            if (_locationItem == null)
+            if (locationItem == null)
             {
                 // Nothing to do.
                 return;
@@ -99,7 +77,7 @@ namespace WeatherInformation
             // TODO: I am setting and getting ApplicationDataObject from different threads!!!! What if I do not see its last value? Do I need synchronization? :/
             WeatherData weatherData = (Application.Current as WeatherInformation.App).ApplicationDataObject;
             if (weatherData != null &&
-                !_locationItem.IsNewLocation &&
+                !locationItem.IsNewLocation &&
                 // TODO: NO ESTOY USANDO GetIsolatedStoredData!!!!!! :(
                 (Application.Current as WeatherInformation.App).IsStoredDataFresh())
             {
@@ -108,17 +86,12 @@ namespace WeatherInformation
             else
             {
                 // Otherwise, call the method that loads data.
-                GetDataAsync();
+                await GetDataAsync(locationItem);
+                // Call UpdateApplicationData on the UI thread.
+                Dispatcher.BeginInvoke(() => UpdateUI());
             }
         }
 
-        // The event handler called when the ApplicationDataObject changes.
-        void MainPage_ApplicationDataObjectChanged(object sender, EventArgs e)
-        {
-            // Call UpdateApplicationData on the UI thread.
-            Dispatcher.BeginInvoke(() => UpdateUI());
-        }
-
         void UpdateUI()
         {
             // Set the ApplicationData and ApplicationDataStatus members of the ViewModel
@@ -137,7 +110,13 @@ namespace WeatherInformation
 
                 _mainViewModel.LoadData(weatherData);
 
-                _locationItem.IsNewLocation = false;        
+                Location locationItem = null;
+                using (var db = new LocationDataContext(LocationDataContext.DBConnectionString))
+                {
+                    locationItem = db.Locations.Where(location => location.IsSelected).FirstOrDefault();
+                    locationItem.IsNewLocation = false;
+                    db.SubmitChanges();
+                }
             }
         }
 
@@ -152,20 +131,20 @@ namespace WeatherInformation
             NavigationService.Navigate(new Uri(uri, UriKind.Relative));
         }
 
-        async private void GetDataAsync()
+        async private Task GetDataAsync(Location locationItem)
         {
             // Gets the data from the web.
             // TODO: multiple threads writing/reading same data :(
-            (Application.Current as WeatherInformation.App).ApplicationDataObject = await LoadDataAsync();
+            (Application.Current as WeatherInformation.App).ApplicationDataObject = await LoadDataAsync(locationItem);
         }
 
         /// <summary>
         /// Retrieve remote weather data.
         /// </summary>
-        async public Task<WeatherData> LoadDataAsync()
+        async public Task<WeatherData> LoadDataAsync(Location locationItem)
         {
-            double latitude = _locationItem.Latitude;
-            double longitude = _locationItem.Longitude;
+            double latitude = locationItem.Latitude;
+            double longitude = locationItem.Longitude;
             int resultsNumber = Convert.ToInt32(AppResources.APIOpenWeatherMapResultsNumber);
 
             CustomHTTPClient httpClient = new CustomHTTPClient();
@@ -181,7 +160,11 @@ namespace WeatherInformation
             string JSONRemoteCurrentWeather = await httpClient.GetWeatherDataAsync(formattedCurrentURL);
 
             var parser = new ServiceParser(new JsonParser());
-            return parser.WeatherDataParser(JSONRemoteForecastWeather, JSONRemoteCurrentWeather);
+            var weatherData = parser.WeatherDataParser(JSONRemoteForecastWeather, JSONRemoteCurrentWeather);
+            weatherData.City = locationItem.City;
+            weatherData.Country = locationItem.Country;
+
+            return weatherData;
         }
 
         private void Location_Click(object sender, EventArgs e)
index 1c1575a..1131802 100644 (file)
@@ -24,8 +24,6 @@ namespace WeatherInformation
 {
     public partial class MapPage : PhoneApplicationPage
     {
-        // Data context for the local database
-        private LocationDataContext _locationDB;
         // TODO anything better than these two instance fields? :(
         private string _city;
         private string _country;
@@ -33,17 +31,19 @@ namespace WeatherInformation
         public MapPage()
         {
             InitializeComponent();
-
-            // Connect to the database and instantiate data context.
-            _locationDB = new LocationDataContext(LocationDataContext.DBConnectionString);
         }
 
         protected override void OnNavigatedTo(NavigationEventArgs e)
         {
+
+            Location locationItem = null;
+            using (var db = new LocationDataContext(LocationDataContext.DBConnectionString))
+            {
+                // Define the query to gather all of the to-do items.
+                // var toDoItemsInDB = from Location location in _locationDB.Locations where location.IsSelected select location;
+                locationItem = db.Locations.Where(location => location.IsSelected).FirstOrDefault();
+            }
             
-            // Define the query to gather all of the to-do items.
-            // var toDoItemsInDB = from Location location in _locationDB.Locations where location.IsSelected select location;
-            var locationItem = _locationDB.Locations.Where(location => location.IsSelected).FirstOrDefault();
             if (locationItem != null)
             {
                 GeoCoordinate geoCoordinate = ConvertLocation(locationItem);
@@ -52,17 +52,6 @@ namespace WeatherInformation
             }
         }
 
-        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
-        {
-            // Call the base method.
-            base.OnNavigatedFrom(e);
-
-            // Save changes to the database.
-            _locationDB.SubmitChanges();
-
-            // No calling _locationDB.Dispose? :/
-        }
-
         private async Task GetCurrentLocationAndUpdateMap()
         {
             Geolocator geolocator = new Geolocator();
@@ -173,40 +162,49 @@ namespace WeatherInformation
         // http://stackoverflow.com/questions/4521435/what-specific-values-can-a-c-sharp-double-represent-that-a-sql-server-float-can
         private void StoreLocation(GeoCoordinate geocoordinate)
         {
-            var locationItem = _locationDB.Locations.Where(location => location.IsSelected).FirstOrDefault();
-            if (locationItem != null)
+            Location locationItem = null;
+            using (var db = new LocationDataContext(LocationDataContext.DBConnectionString))
             {
-                locationItem.Latitude = geocoordinate.Latitude;
-                locationItem.Longitude = geocoordinate.Longitude;
-                locationItem.Altitude = geocoordinate.Altitude;
-                locationItem.City = _city ?? "";
-                locationItem.Country = _country ?? "";
-                locationItem.HorizontalAccuracy = geocoordinate.HorizontalAccuracy;
-                locationItem.VerticalAccuracy = geocoordinate.VerticalAccuracy;
-                locationItem.Speed = geocoordinate.Speed;
-                locationItem.Course = geocoordinate.Course;
-                locationItem.IsNewLocation = true;
-                locationItem.IsSelected = true;
-            }
-            else
-            {
-                locationItem = new Location()
+                // Define the query to gather all of the to-do items.
+                // var toDoItemsInDB = from Location location in _locationDB.Locations where location.IsSelected select location;
+                locationItem = db.Locations.Where(location => location.IsSelected).FirstOrDefault();
+
+                if (locationItem != null)
                 {
-                    Latitude = geocoordinate.Latitude,
-                    Longitude = geocoordinate.Longitude,
-                    Altitude = geocoordinate.Altitude,
-                    City = _city ?? "",
-                    Country = _country ?? "",
-                    HorizontalAccuracy = geocoordinate.HorizontalAccuracy,
-                    VerticalAccuracy = geocoordinate.VerticalAccuracy,
-                    Speed = geocoordinate.Speed,
-                    Course = geocoordinate.Course,
-                    IsNewLocation = true,
-                    IsSelected = true,
-                };
+                    locationItem.Latitude = geocoordinate.Latitude;
+                    locationItem.Longitude = geocoordinate.Longitude;
+                    locationItem.Altitude = geocoordinate.Altitude;
+                    locationItem.City = _city ?? "";
+                    locationItem.Country = _country ?? "";
+                    locationItem.HorizontalAccuracy = geocoordinate.HorizontalAccuracy;
+                    locationItem.VerticalAccuracy = geocoordinate.VerticalAccuracy;
+                    locationItem.Speed = geocoordinate.Speed;
+                    locationItem.Course = geocoordinate.Course;
+                    locationItem.IsNewLocation = true;
+                    locationItem.IsSelected = true;
+                }
+                else
+                {
+                    locationItem = new Location()
+                    {
+                        Latitude = geocoordinate.Latitude,
+                        Longitude = geocoordinate.Longitude,
+                        Altitude = geocoordinate.Altitude,
+                        City = _city ?? "",
+                        Country = _country ?? "",
+                        HorizontalAccuracy = geocoordinate.HorizontalAccuracy,
+                        VerticalAccuracy = geocoordinate.VerticalAccuracy,
+                        Speed = geocoordinate.Speed,
+                        Course = geocoordinate.Course,
+                        IsNewLocation = true,
+                        IsSelected = true,
+                    };
+
+                    // Add a location item to the local database.
+                    db.Locations.InsertOnSubmit(locationItem);
+                }
 
-                // Add a location item to the local database.
-                _locationDB.Locations.InsertOnSubmit(locationItem);
+                db.SubmitChanges();
             }
         }