MaxMind Geolite city is free. If it is not good enough, you can apparently upgrade to a more accurate paid-version. I can't speak for the quality of the paid version, as I have never used it.
If you like your SQL, download the CSV version. Load it into your database of choice, and query away.
The faster and space-efficient option is to download the file binary blob version of the same database, and then use the C# class to query it.
Alternatively, I have found ipinfodb.com to be useful. Query is by simple HTTP GET. For example, to geolocate stackoverflow.com try:
http://ipinfodb.com/ip_query.php?timezone=false&ip=69.59.196.211
This will return an XML file containing latitude and longitude, that looks like:
<Response>
<Ip>69.59.196.211</Ip>
<Status>OK</Status>
<CountryCode>US</CountryCode>
<CountryName>United States</CountryName>
<RegionCode>41</RegionCode>
<RegionName>Oregon</RegionName>
<City>Corvallis</City>
<ZipPostalCode>97333</ZipPostalCode>
<Latitude>44.4698</Latitude>
<Longitude>-123.343</Longitude>
</Response>
Some VB.NET sample code is available at http://forum.ipinfodb.com/viewtopic.php?f=7&t=269
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…