Posted by david on 5. February 2009 00:19
Plan: update POI table with lat & long values retrieved from geocode service. get a zip code field into the POI table.
Listening to: CBC Radio’s Climate Wars Part 1 of 3
----------------------------
Copy 2009_02_04 to 2009_02_05.
Dropped the Raj Kaimal code – don’t need it right now since I dropped the DetailsView table.
Update selected record with retrieved lat & long
Research:
Using LINQ in ASP.NET (Part 1)
(2) MSDN: How to: Update, Insert, and Delete Data with the LinqDataSource Control
Following (2):
create a _RowUpdating event
create an entity class for the table: POI entityPOI = new POI();
oooh that’s cool. the entity class just created is an object that represents the table, it’s properties are the table fields.
the MSDN example (2) only had code example for inserting new record.
More Research:
Scott Gu Using LINQ to SQL very nice, detailed, code rich 5 part post.
see, you can allow gridview to handle updates. So, I suppose, I could have the geoservice fill the lat & long fields right in the grid view for the selected record, then it would update itself.
But I’m trying to update the table directly from code. Then I’ll have the gridview reflect my changes.
OK, poking through stuff, I see it’s absolutely possible …
NorthwindDataContext db = new NorthwindDataContext();
Product product = db.Products.Single(p => p.ProductName == "Toy 1");
product.UnitPrice = 99;
product.UnitsInStock = 5;
db.SubmitChanges();
(3)
First, though, I need the primary key of the row.
Create another literal on the page:
<div class="SelectedRecordRow">
<asp:Label ID="LabelSelectedPOI_ID" runat="server" Text="POI ID: "></asp:Label>
<asp:Literal ID="LiteralPOI_ID" runat="server"></asp:Literal>
</div>
Then in the POIgrid_SelectedIndexChanged handler,
LiteralPOI_ID.Text = POIgrid.SelectedValue.ToString();
so now I know I’ve got my id.
build a class to handle the update, with properties latitude, longitude, and primary key … big help from (3, page 5) for demonstrating how to build the linq update.
using System.Text;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using net.virtualearth.common.staging;
using dev.virtualearth.net.webservices.v1.geocode;
using VEWSGeoservice;
namespace MapsiteUpdater
{
public class UpdatePOI
{
private double targetLatitude;
private double targetLongitude;
private int targetPOI_ID;
public double TargetLatitude
{
get
{ return targetLatitude; }
set
{ targetLatitude = value; }
}
public double TargetLongitude
{
get
{ return targetLongitude; }
set
{ targetLongitude = value; }
}
public int TargetPOI_ID
{
get
{ return targetPOI_ID; }
set
{ targetPOI_ID = value; }
}
public UpdatePOI()
{
//
// TODO: Add constructor logic here
//
}
public bool updateLatLong()
{
mapsiteLinqToSQLDataContext db = new mapsiteLinqToSQLDataContext();
POI entityPOI = db.POIs.Single(p => p.POI_ID == TargetPOI_ID);
entityPOI.POI_Latitude = TargetLatitude;
entityPOI.POI_Longitude = TargetLongitude;
db.SubmitChanges();
return true;
}
}
}
& that works … it is called by this:
protected void POIgrid_SelectedIndexChanged(object sender, EventArgs e)
{
GridViewRow CurrentRow = POIgrid.Rows[POIgrid.SelectedIndex];
StringBuilder CompleteAddress = new StringBuilder();
CompleteAddress.Append(CurrentRow.Cells[2].Text);
CompleteAddress.Append(" ");
CompleteAddress.Append(CurrentRow.Cells[3].Text);
CompleteAddress.Append(" ");
CompleteAddress.Append(CurrentRow.Cells[4].Text);
literalWholeAddress.Text = CompleteAddress.ToString();
string addressInput = CompleteAddress.ToString();
LatLong resultLatLong = new LatLong();
VEWSGeo myVEWSGeo = new VEWSGeo();
myVEWSGeo.ClientIP = Page.Request.UserHostAddress;
//View
resultLatLong = myVEWSGeo.GetLatLong(addressInput);
LiteralLatitude.Text = resultLatLong.Latitude.ToString();
LiteralLongitude.Text = resultLatLong.Longitude.ToString();
LiteralPOI_ID.Text = POIgrid.SelectedValue.ToString();
//Data
UpdatePOI myUpdatePOI = new UpdatePOI();
myUpdatePOI.TargetPOI_ID = Convert.ToInt32(POIgrid.SelectedValue.ToString());
myUpdatePOI.TargetLatitude = resultLatLong.Latitude;
myUpdatePOI.TargetLongitude = resultLatLong.Longitude;
myUpdatePOI.updateLatLong();
}
still seems like an awful lot of code to be on the page … I’m sure I’ve got a lot to clean up here … but it’s functional. When user selects a new row in POIgrid, an UpdatePOI object is created, setting it’s latitude & longitude & target POI_ID. Then UpdatePOI.UpdateLatLong is called. It updates the table for that particular record.
I knew it was working because if I refreshed the page, the new lat long values were displayed in the appropriate records. However, it wasn’t refreshing after the update. I need to rebind the grid with a
POIgrid.DataBind();
i threw a button down there with that as the click event and it worked … the grid refreshes, showing the new stuff.
Now, how to do it automagically?
The RowUpdated event doesn’t fire because I was doing it in the code behind.
The Datasource updated event doesn’t fire either ….
i can’t stick the databind() after the update command because it takes a couple secs for it to process ….
Easy fix would be to throw the databind on a timer refresh … but that’s kinda weak. It’s a waste of resources, because it’ll be firing every 30 sec or whatever.
Wonder if I can get at the process that handles the UpdatePanel progress … I had left the graphic off of this version …
will try it in the UpdateProgress1_Disposed
nope – that didn’t work
if !postback on the page load didn’t work
I’ve tried this a bagillion different ways: hidden field, textbox.text changed, calling the buttonclick programmatically … can’t figure it out.
But – progress has been made … 5 yards or so. 2nd down
Final page tonight: 2009_02_05
- http://www.dotnetbips.com/articles/56f8f29d-2617-4f99-a8b4-977703ebf780.aspx
- MSDN: How to: Update, Insert, and Delete Data with the LinqDataSource Control
- Scott Guthrie, “Using LINQ To Sql,” http://www.scribd.com/doc/6046235/LINQ-To-Sql.