<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Rob Tiffany &#187; .NET</title>
	<atom:link href="http://robtiffany.com/tag/net/feed/" rel="self" type="application/rss+xml" />
	<link>http://robtiffany.com</link>
	<description>Author, Mobility Strategist at Microsoft, Speaker, Advisor, Technology Executive, Former Navy Submariner</description>
	<lastBuildDate>Wed, 16 May 2012 01:19:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>What Developers in Small Companies are Using</title>
		<link>http://robtiffany.com/what-developers-in-small-companies-are-using/</link>
		<comments>http://robtiffany.com/what-developers-in-small-companies-are-using/#comments</comments>
		<pubDate>Fri, 09 Dec 2011 17:01:44 +0000</pubDate>
		<dc:creator>Rob Tiffany</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Bug Tracking]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Developer]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[Project Management]]></category>
		<category><![CDATA[Storage]]></category>
		<category><![CDATA[Text Editor]]></category>
		<category><![CDATA[Version Control]]></category>
		<category><![CDATA[Web Hosting]]></category>
		<category><![CDATA[Website Analytics]]></category>

		<guid isPermaLink="false">http://robtiffany.com/software/what-developers-in-small-companies-are-using</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p><img src="http://api.viglink.com/api/click?format=go&amp;key=021de175e1e571c67cfaeea3c68d72e8&amp;loc=http%3A%2F%2Fwww.readwriteweb.com%2Fhack%2F2011%2F12%2Finfographic-what-tools-develop.php&amp;v=1&amp;libid=1323449648031&amp;out=http%3A%2F%2Frww.readwriteweb.netdna-cdn.com%2Fhack%2FBV%2520Developer%2520Infographic.jpg&amp;ref=http%3A%2F%2Fwww.readwriteweb.com%2F&amp;title=Infographic%3A%20What%20Tools%20Developers%20Actually%20Use&amp;txt=&amp;jsonp=vglnk_jsonp_13234496851722" width="1199" height="3687" /></p>
]]></content:encoded>
			<wfw:commentRss>http://robtiffany.com/what-developers-in-small-companies-are-using/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Windows 7 Slates: Touch-First UIs</title>
		<link>http://robtiffany.com/windows-7-slates-touchfirst-uis/</link>
		<comments>http://robtiffany.com/windows-7-slates-touchfirst-uis/#comments</comments>
		<pubDate>Wed, 17 Aug 2011 01:51:48 +0000</pubDate>
		<dc:creator>Rob Tiffany</dc:creator>
				<category><![CDATA[Windows 7]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Consumerization]]></category>
		<category><![CDATA[Slate]]></category>
		<category><![CDATA[Tablet]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[UX]]></category>

		<guid isPermaLink="false">http://robtiffany.com/?p=870</guid>
		<description><![CDATA[When it comes to building apps with &#8220;Touch-First&#8221; user interfaces for Windows 7 Slates, there are a few principles you need to follow.  Instead of talking about gestures, swiping, pinching or receiving multi-touch Windows messages, I&#8217;m going to stick to &#8230; <a href="http://robtiffany.com/windows-7-slates-touchfirst-uis/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>When it comes to building apps with &#8220;Touch-First&#8221; user interfaces for Windows 7 Slates, there are a few principles you need to follow.  Instead of talking about gestures, swiping, pinching or receiving multi-touch Windows messages, I&#8217;m going to stick to the basics in this article.  I’m not an artist or UX guru, but I have been designing user interfaces for mobile and embedded devices with small screens since the late 90’s.</p>
<p><strong>Runtime</strong></p>
<p>If you remember the last time I talked about Windows 7 Slate development, I mentioned that plain-old .NET WinForms are actually a great choice.  Since every copy of Windows 7 includes .NET 3.51 as part of the image, you might consider targeting that runtime or C++ for friction-free deployment and best performance if it gives you the functionality you&#8217;re looking for.  Performance-tuned, Xaml-based apps are also an option as long as you&#8217;re not targeting Tablets with low-end CPUs and poor-performing, integrated graphics.  The same advice goes for HTML5 as long as you&#8217;re running IE9.</p>
<p><strong>Immersive</strong></p>
<p>Creating an immersive app that takes over the entire screen is step one.  This means that when you design your WinForms in Visual Studio, set them to be Maximized and get rid of the Control Box, Minimize/Maximize buttons, and the Border.</p>
<p>In the Spash Screen below, you can see it completely takes up the entire screen of the Tablet:</p>
<p><a href="http://robtiffany.com/windows-7/windows-7-slates-touchfirst-uis/attachment/splashsm" rel="attachment wp-att-876"><img class="alignleft size-full wp-image-876" title="SplashSM" src="http://robtiffany.com/wp-content/uploads/2011/08/SplashSM.jpg" alt="" width="448" height="336" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong>UI Element Size</strong></p>
<p>Since some people have been known to have fingers as large as 80 pixels wide, you can no longer get by with the default sizes of UI elements when you drag them from the toolbox.  You need to increase the size of UI elements to be 40+ pixels wide/high as appropriate to users a large hit target for their fingers.</p>
<p>In the Login Screen below, you can see a giant power button icon in the upper-right side as well as a large User selection combo box, Password text box and Login button:</p>
<p><a href="http://robtiffany.com/windows-7/windows-7-slates-touchfirst-uis/attachment/loginsm" rel="attachment wp-att-873"><img class="alignright size-full wp-image-873" title="LoginSM" src="http://robtiffany.com/wp-content/uploads/2011/08/LoginSM.jpg" alt="" width="448" height="336" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong>UI Element Spacing</strong></p>
<p>Besides making UI elements larger, you also need to make them farther apart.  I know this flies in the face of you desire to cram as many things on a screen as possible.  Each screen should provide just a single function or idea so keep it simple, uncluttered, and elegant.  The term &#8220;fat finger&#8221; exists for a reason.  In order to prevent accidentally tapping on the wrong button, space all UI elements at least 20+ pixels apart.</p>
<p>In the Reservations Screen below, you can see a date picker, combo boxes, a button, and check boxes that are easy to touch and give each other breathing room:</p>
<p><a href="http://robtiffany.com/windows-7/windows-7-slates-touchfirst-uis/attachment/reservationsm" rel="attachment wp-att-877"><img class="alignleft size-full wp-image-877" title="ReservationSM" src="http://robtiffany.com/wp-content/uploads/2011/08/ReservationSM.jpg" alt="" width="448" height="336" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong>Go Big!</strong></p>
<p>Get accustomed to making everything bigger because the presentation paradigm for a Tablet is fundamentally different.  You don&#8217;t have the precision of a mouse to click on small hit targets.  You should also pump up the size of things you don&#8217;t touch, like the font of text on a screen so it&#8217;s clearly visible to the user from any angle.  Large, beautiful, typography as well as iconography is a good thing.</p>
<p>In the Schedule Screen below, you can see a large grid with big cells and text with large font.  The screen title is big and so is the arrow icon used to close and return to the previous screen.</p>
<p><a href="http://robtiffany.com/windows-7/windows-7-slates-touchfirst-uis/attachment/schedulessm" rel="attachment wp-att-875"><img class="alignright size-full wp-image-875" title="SchedulesSM" src="http://robtiffany.com/wp-content/uploads/2011/08/SchedulesSM.jpg" alt="" width="448" height="336" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong>One More Thing</strong></p>
<p>In the touch-first world of mobile devices, you can never assume the use of a keyboard.  That&#8217;s why it&#8217;s important not to throw lots of empty text boxes at users to fill in.  It&#8217;s cumbersome and slow and a user may choose to not use your app.  Give users finger-friendly choices via UI elements like radio buttons, combo boxes and checkboxes where possible.</p>
<p>Now go start building those Touch-First UIs for today&#8217;s Windows 7 Slates!</p>
<p>Rob</p>
]]></content:encoded>
			<wfw:commentRss>http://robtiffany.com/windows-7-slates-touchfirst-uis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows 7 Slates: Rapid App Deployment</title>
		<link>http://robtiffany.com/windows-7-slates-development-tip-1/</link>
		<comments>http://robtiffany.com/windows-7-slates-development-tip-1/#comments</comments>
		<pubDate>Fri, 15 Jul 2011 05:33:04 +0000</pubDate>
		<dc:creator>Rob Tiffany</dc:creator>
				<category><![CDATA[Windows 7]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Consumerization]]></category>
		<category><![CDATA[Slate]]></category>
		<category><![CDATA[Tablet]]></category>

		<guid isPermaLink="false">http://robtiffany.com/?p=796</guid>
		<description><![CDATA[If you're delivering an app that requires all the power of .NET though, you might consider using version 3.51 since it's part of the Windows 7 OS image. <a href="http://robtiffany.com/windows-7-slates-development-tip-1/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The tablet craze is really in full swing and new Windows 7 devices are being released almost every week.  Consumers and business users alike are snapping up these tablets and they want to be productive with apps right away.  Yes, they&#8217;re treating these wireless devices just like they&#8217;re Smartphones or iPads.  As well they should!  This means that aside from Microsoft Office, they&#8217;re expecting to quickly download apps from the Internet or various marketplaces without a lot of fuss.  This means no DVDs.</p>
<p>One way to ensure fast, seamless downloads of your apps is to not take dependencies on large runtimes, installation media, or plugins that may not already be installed on Windows 7 by default.  Silverlight isn&#8217;t a big deal because the plugin is very small and should download and install quickly along with your app.  If you&#8217;re delivering an app that requires all the power of .NET though, you might consider using version 3.51 since it&#8217;s part of the Windows 7 OS image.</p>
<p>Don&#8217;t flame me for not recommending .NET 4.0, I use it all the time.  That being said, if the requirments of your WinForm app are met by the features and base class libraries found in .NET 3.51, then don&#8217;t unnecessarily take dependency on 4.  Your app will download, install and run without any extra steps.  This is not unlike how most Windows Mobile enterprise customers over the last decade targeted the version of the .NET Compact Framework found in ROM instead of taking advantage of the extra features found in version 3.5.  It frustrated me for a while, but I finally got it.</p>
<p>The Consumerization of IT must drive new behaviors by corporations.  Speed and simplicity of app deployment to employees is one of those behaviors.</p>
<p>Keep Coding,</p>
<p>Rob</p>
]]></content:encoded>
			<wfw:commentRss>http://robtiffany.com/windows-7-slates-development-tip-1/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Windows Phone 7 Line of Business App Dev :: Uploading Data back to Azure</title>
		<link>http://robtiffany.com/windows-phone-7-line-of-business-app-dev-uploading-data-back-to-azure/</link>
		<comments>http://robtiffany.com/windows-phone-7-line-of-business-app-dev-uploading-data-back-to-azure/#comments</comments>
		<pubDate>Wed, 04 May 2011 05:11:35 +0000</pubDate>
		<dc:creator>Rob Tiffany</dc:creator>
				<category><![CDATA[Windows Phone 7]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Azure Queues]]></category>
		<category><![CDATA[Azure Table Storage]]></category>
		<category><![CDATA[Data Contract]]></category>
		<category><![CDATA[Data Member]]></category>
		<category><![CDATA[DataContractJsonSerializer]]></category>
		<category><![CDATA[DELETE]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[GET]]></category>
		<category><![CDATA[Hadoop]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Loosely-coupled]]></category>
		<category><![CDATA[Memcache]]></category>
		<category><![CDATA[MemoryStream]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[POST]]></category>
		<category><![CDATA[PUT]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Slate]]></category>
		<category><![CDATA[SQL Azure]]></category>
		<category><![CDATA[Tablet]]></category>
		<category><![CDATA[URI]]></category>
		<category><![CDATA[UriTemplate]]></category>
		<category><![CDATA[WCF]]></category>
		<category><![CDATA[WebClient]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Windows 7]]></category>
		<category><![CDATA[Windows Communication Foundation]]></category>
		<category><![CDATA[Windows phone]]></category>
		<category><![CDATA[Windows Slate]]></category>
		<category><![CDATA[Wireless]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[XmlSerializer]]></category>

		<guid isPermaLink="false">http://robtiffany.com/windows-phone-7/windows-phone-7-line-of-business-app-dev-uploading-data-back-to-azure</guid>
		<description><![CDATA[Looking back over the last 6 months of this series of articles, you’ve created wireless-efficient WCF REST + JSON Web Services in Azure to download data from SQL Azure tables to Windows Phone.  You’ve maintained in-memory collections of objects in &#8230; <a href="http://robtiffany.com/windows-phone-7-line-of-business-app-dev-uploading-data-back-to-azure/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div>Looking back over the last 6 months of this series of articles, you’ve created wireless-efficient <strong>WCF REST + JSON</strong> Web Services in <strong>Azure</strong> to download data from <strong>SQL Azure</strong> tables to <strong>Windows Phone</strong>.  You’ve maintained in-memory collections of objects in your own local <strong>NoSQL</strong> object cache.  You&#8217;ve used <strong>LINQ</strong> to query those collections and bind results to various <strong>Silverlight</strong> UI elements.  You’ve even serialized those collections to <strong>Isolated Storage</strong> using memory-efficient JSON.  So what’s left to do?</div>
<div><a href="http://robtiffany.com/wp-content/uploads/2011/05/Sub.png"><img class="aligncenter size-medium wp-image-681" title="Submarine" src="http://robtiffany.com/wp-content/uploads/2011/05/Sub-180x300.png" alt="" width="180" height="300" /></a></div>
<div></div>
<div>Oh yeah, I guess you might want to know how to <strong>upload</strong> an object full to data back to a WCF Web Service in Azure.  In order to keep this article simple and to-the-point, I’m going to work with a basic Submarine object and show you how to fill it with data and upload it from a <strong>Windows Phone</strong> or <strong>Slate</strong> to a WCF REST + JSON Web Service.  Let’s take a look at this object:</div>
<div></div>
<div><span style="font-family: Consolas;">using System;<br />
using System.Collections.Generic;<br />
using System.Linq;<br />
using System.Text;<br />
using System.Runtime.Serialization;</span></div>
<div><span style="font-family: Consolas;">namespace Models<br />
{<br />
[DataContract()]<br />
public class Submarine<br />
{<br />
[DataMember()]<br />
public int Id { get; set; }<br />
[DataMember()]<br />
public string Name { get; set; }<br />
}<br />
}</span></div>
<div></div>
<div>It includes just an integer data type called <strong>Id</strong>, and a string called <strong>Name</strong>.  As in previous articles before, its decorated with a <strong>[DataContract()]</strong> and two <strong>[DataMember()]</strong>s to allow<strong> .NET serialization</strong> to do its thing.  So the next thing we need to do is create and populate this Submarine object with data, serialize it as JSON, and send it on its way using <strong>WebClient</strong>.</div>
<div></div>
<div>Below is the method and its callback that accomplishes this:</div>
<div></div>
<div><span style="font-family: Consolas;">using System;<br />
using System.Collections.Generic;<br />
using System.Linq;<br />
using System.Net;<br />
using System.Windows;<br />
using Microsoft.Phone.Controls;<br />
using System.IO;<br />
using System.Runtime.Serialization.Json;<br />
using System.Text;</span></div>
<div><span style="font-family: Consolas;">private void AddSubmarine()<br />
{<br />
Uri uri = new Uri(&#8220;</span><a href="http://127.0.0.1:81/SubService.svc/AddSubmarine&quot;);"><span style="font-family: Consolas;">http://127.0.0.1:81/SubService.svc/AddSubmarine&#8221;);</span></a></div>
<div><span style="font-family: Consolas;"> Models.Submarine submarine = new Models.Submarine() { Id = 3, Name = &#8220;Seawolf&#8221; };<br />
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Models.Submarine));<br />
MemoryStream mem = new MemoryStream();<br />
ser.WriteObject(mem, submarine);<br />
string data = Encoding.UTF8.GetString(mem.ToArray(), 0, (int)mem.Length);</span></div>
<div><span style="font-family: Consolas;"> WebClient webClient = new WebClient();<br />
webClient.UploadStringCompleted += new UploadStringCompletedEventHandler(webClient _UploadStringCompleted);<br />
webClient.Headers["Content-type"] = &#8220;application/json&#8221;;<br />
webClient.Encoding = Encoding.UTF8;<br />
webClient.UploadStringAsync(uri, &#8220;POST&#8221;, data);</span></div>
<div><span style="font-family: Consolas;">}</span></div>
<div><span style="font-family: Consolas;">void webClient_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)<br />
{<br />
var x = e.Result;<br />
}</span></div>
<div></div>
<div>As you can see above, I point the <strong>URI</strong> at a WCF Service called <strong>SubService.svc/AddSubmarine</strong>.  How <strong>RESTful</strong>.  Next, I create an instance of the Submarine object, give it an <strong>Id</strong> of <strong>3</strong> and the <strong>Name</strong> <strong>Seawolf</strong>.  I then use the same <strong>DataContractJsonSerializer</strong> I’ve been using in all the other articles to serialize the Submarine object to a JSON representation.  Using the <strong>MemoryStream</strong>, I write the JSON to a stream and then artfully turn it into a string.  Last but not least, I instantiate a new WebClient object, create an event handler for a callback, and upload the <strong>stringified</strong> Submarine object to the WCF Service.</div>
<div></div>
<div>So where did I upload the Submarine object to?</div>
<div></div>
<div>It takes two to Mango, so let’s take a look.  For starters, it goes without saying that every WCF Service starts with an <strong>Interface</strong>.  This one is called<strong> ISubService.cs</strong>:</div>
<div></div>
<div><span style="font-family: Consolas;">using System;<br />
using System.Collections.Generic;<br />
using System.Linq;<br />
using System.Runtime.Serialization;<br />
using System.ServiceModel;<br />
using System.ServiceModel.Web;<br />
using System.Text;</span></div>
<div><span style="font-family: Consolas;">namespace DataSync<br />
{<br />
[ServiceContract]<br />
public interface ISubService<br />
{<br />
</span><span style="font-family: Consolas;">[OperationContract]<br />
[WebInvoke(UriTemplate = "/AddSubmarine", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, Method = "POST")]<br />
bool AddSubmarine(Models.Submarine sub);</span></div>
<div><span style="font-family: Consolas;"> }<br />
}</span></div>
<div></div>
<div>Unlike previous articles where I had you download data with <strong>WebGet</strong>, this time I’m using <strong>WebInvoke</strong> to denote that a <strong>PUT</strong>, <strong>POST</strong>, or <strong>DELETE</strong> <strong>HTTP</strong> <strong>Verb</strong> is being used with our <strong>REST</strong> service.  The <strong>UriTemplate</strong> gives you the RESTful <strong>/AddSubmarine</strong>, and I added the <strong>Method = “POST”</strong> for good measure.  Keep in mind that you’ll need the exact same Submarine class on the server that you had on your Windows Phone to make all this work.</div>
<div></div>
<div>Let’s see what we get when we <strong>Implement this Interface</strong>:</div>
<div></div>
<div><span style="font-family: Consolas;">using System;<br />
using System.Collections.Generic;<br />
using System.Linq;<br />
using System.Runtime.Serialization;<br />
using System.ServiceModel;<br />
using System.ServiceModel.Web;<br />
using System.Text;<br />
using Microsoft.WindowsAzure;<br />
using Microsoft.WindowsAzure.Diagnostics;<br />
using Microsoft.WindowsAzure.ServiceRuntime;<br />
using Microsoft.WindowsAzure.StorageClient;<br />
using System.Configuration;<br />
using System.Xml.Serialization;<br />
using System.IO;</span></div>
<div><span style="font-family: Consolas;">namespace DataSync<br />
{<br />
public class SubService : ISubService<br />
{<br />
public SubService()<br />
{ </span></div>
<div><span style="font-family: Consolas;"></p>
<div>}</div>
<p></span></div>
<div><span style="font-family: Consolas;"> public bool AddSubmarine(Models.Submarine submarine)<br />
{<br />
try<br />
{<br />
if (submarine != null)<br />
{<br />
//Do something with your Deserialized .NET Submarine Object<br />
//… = submarine.Id </span><span style="font-family: Consolas;"> //… = submarine.Name</span></div>
<div><span style="font-family: Consolas;"> return true;<br />
}<br />
else<br />
{<br />
return false;<br />
}<br />
}<br />
catch<br />
{<br />
return false;<br />
}<br />
}</span></div>
<div><span style="font-family: Consolas;"> }<br />
}</span></div>
<div></div>
<div>Here we end up with <strong>SubService.svc</strong> with the simple <strong>AddSubmarine</strong> method where you pass in a Submarine object as a parameter.  What you do with this object, I’ll leave to you.  Some might be tempted to INSERT it into <strong>SQL Azure</strong>.  I’d prefer that you drop it into an <strong>Azure Queue</strong> and have a <strong>Worker Role</strong> do the INSERTing later so you can stay <strong>loosely-coupled</strong>.  Just in case you need a refresher on a REST-based <strong>Web.config</strong> file, here’s one below:</div>
<div></div>
<div><span style="font-family: Consolas;">&lt;?xml version=&#8221;1.0&#8243;?&gt;<br />
&lt;configuration&gt;<br />
&lt;!&#8211;  To collect diagnostic traces, uncomment the section below.<br />
To persist the traces to storage, update the DiagnosticsConnectionString setting with your storage credentials.<br />
To avoid performance degradation, remember to disable tracing on production deployments.<br />
&lt;system.diagnostics&gt;<br />
&lt;sharedListeners&gt;<br />
&lt;add name=&#8221;AzureLocalStorage&#8221; type=&#8221;DataSync.AzureLocalStorageTraceListener, DataSync&#8221;/&gt;<br />
&lt;/sharedListeners&gt;<br />
&lt;sources&gt;<br />
&lt;source name=&#8221;System.ServiceModel&#8221; switchValue=&#8221;Verbose, ActivityTracing&#8221;&gt;<br />
&lt;listeners&gt;<br />
&lt;add name=&#8221;AzureLocalStorage&#8221;/&gt;<br />
&lt;/listeners&gt;<br />
&lt;/source&gt;<br />
&lt;source name=&#8221;System.ServiceModel.MessageLogging&#8221; switchValue=&#8221;Verbose&#8221;&gt;<br />
&lt;listeners&gt;<br />
&lt;add name=&#8221;AzureLocalStorage&#8221;/&gt;<br />
&lt;/listeners&gt;<br />
&lt;/source&gt;<br />
&lt;/sources&gt;<br />
&lt;/system.diagnostics&gt; &#8211;&gt;<br />
&lt;system.diagnostics&gt;<br />
&lt;trace&gt;<br />
&lt;listeners&gt;<br />
&lt;add type=&#8221;Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&#8243;<br />
name=&#8221;AzureDiagnostics&#8221;&gt;<br />
&lt;filter type=&#8221;" /&gt;<br />
&lt;/add&gt;<br />
&lt;/listeners&gt;<br />
&lt;/trace&gt;<br />
&lt;/system.diagnostics&gt;<br />
&lt;system.web&gt;<br />
&lt;compilation debug=&#8221;true&#8221; targetFramework=&#8221;4.0&#8243; /&gt;</span></div>
<div><span style="font-family: Consolas;"> &lt;/system.web&gt;</span></div>
<div><span style="font-family: Consolas;"> &lt;!&#8211;Add Connection Strings&#8211;&gt;<br />
&lt;connectionStrings&gt; </span></div>
<div><span style="font-family: Consolas;"></p>
<div>&lt;/connectionStrings&gt;</div>
<p></span></div>
<div><span style="font-family: Consolas;"> &lt;system.serviceModel&gt;<br />
&lt;behaviors&gt;<br />
&lt;serviceBehaviors&gt;<br />
&lt;behavior&gt;<br />
&lt;!&#8211; To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment &#8211;&gt;<br />
&lt;serviceMetadata httpGetEnabled=&#8221;true&#8221;/&gt;<br />
&lt;!&#8211; To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information &#8211;&gt;<br />
&lt;serviceDebug includeExceptionDetailInFaults=&#8221;false&#8221;/&gt;<br />
&lt;/behavior&gt;<br />
&lt;/serviceBehaviors&gt;</span></div>
<div><span style="font-family: Consolas;"> &lt;!&#8211;Add REST Endpoint Behavior&#8211;&gt;<br />
&lt;endpointBehaviors&gt;<br />
&lt;behavior name=&#8221;REST&#8221;&gt;<br />
&lt;webHttp /&gt;<br />
&lt;/behavior&gt;<br />
&lt;/endpointBehaviors&gt;</span></div>
<div><span style="font-family: Consolas;"> &lt;/behaviors&gt;</span></div>
<div><span style="font-family: Consolas;"> &lt;!&#8211;Add Service with webHttpBinding&#8211;&gt;<br />
&lt;services&gt;<br />
&lt;service name=&#8221;DataSync.SubService&#8221;&gt;<br />
&lt;endpoint address=&#8221;" behaviorConfiguration=&#8221;REST&#8221; binding=&#8221;webHttpBinding&#8221;<br />
contract=&#8221;DataSync.ISubService&#8221; /&gt;<br />
&lt;/service&gt;<br />
&lt;/services&gt;</span></div>
<div><span style="font-family: Consolas;"> &lt;serviceHostingEnvironment aspNetCompatibilityEnabled=&#8221;true&#8221; multipleSiteBindingsEnabled=&#8221;true&#8221; /&gt;</span></div>
<div><span style="font-family: Consolas;"> &lt;!&#8211;&lt;serviceHostingEnvironment multipleSiteBindingsEnabled=&#8221;true&#8221; /&gt;&#8211;&gt;<br />
&lt;/system.serviceModel&gt;<br />
&lt;system.webServer&gt;<br />
&lt;modules runAllManagedModulesForAllRequests=&#8221;true&#8221;/&gt;<br />
&lt;/system.webServer&gt;<br />
&lt;/configuration&gt;</span></div>
<div></div>
<div>This Web.Config gives you the <strong>webHttpBinding</strong> you’re looking for to do a <strong>REST</strong> service.  I even left you a spot to add your own database or Azure storage <strong>connection strings</strong>.</div>
<div>This article wraps up the <strong>Windows Phone 7 Line of Business App Dev series</strong> that I’ve been delivering to you since last September.  Who knew I would make fun of <strong>OData</strong> or have you create your own <strong>NoSQL</strong> database to run on your phone along the way?  I think I actually wrote the first article in this series from a hotel room in <strong>Nantes, France</strong>.</div>
<div></div>
<div>But have no fear, this isn’t the end.</div>
<div></div>
<div>In preparation for <strong>Tech Ed 2010 North America</strong> coming up on May 16th in Atlanta, I’ve been building the <strong>next-gen</strong>, <strong>super-fast</strong>, <strong>super-scalable Azure architecture</strong> designed for <strong>mobile devices roaming on wireless data networks</strong>.  I’ve spent the last decade building the world’s largest and most scalable mobile infrastructures for Microsoft’s wonderful global customers.  Now it’s time to make the jump from supporting <strong>enterprise-level scalability</strong> to the much bigger <strong>consumer-level scalability</strong>.</div>
<div></div>
<div>Yes, I’m talking <strong>millions</strong> of devices.</div>
<div></div>
<div>No, you won’t have to recreate <strong>Facebook’s</strong> servers, <strong>NoSQL</strong>, <strong>Memcache</strong>, or <strong>Hadoop</strong> infrastructure to make it happen.  I’m going to show you how to make it happen with Azure in just two weeks so I’m looking forward to seeing everyone in Atlanta in two weeks.</div>
<div></div>
<div>Keep coding,</div>
<div>Rob</div>
]]></content:encoded>
			<wfw:commentRss>http://robtiffany.com/windows-phone-7-line-of-business-app-dev-uploading-data-back-to-azure/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Windows Phone 7 Line of Business App Dev :: Improving the In-Memory Database</title>
		<link>http://robtiffany.com/windows-phone-7-line-of-business-app-dev-improving-the-in-memory-database/</link>
		<comments>http://robtiffany.com/windows-phone-7-line-of-business-app-dev-improving-the-in-memory-database/#comments</comments>
		<pubDate>Sat, 27 Nov 2010 07:19:51 +0000</pubDate>
		<dc:creator>Rob Tiffany</dc:creator>
				<category><![CDATA[Windows Phone 7]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[AutoFlush]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Chage-tracking]]></category>
		<category><![CDATA[Column]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[DataContractJsonSerializer]]></category>
		<category><![CDATA[DML]]></category>
		<category><![CDATA[Isolated Storage]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[LINQ]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[ObservableCollection]]></category>
		<category><![CDATA[Occasionally-connected]]></category>
		<category><![CDATA[RDA]]></category>
		<category><![CDATA[Remote Data Access]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Row]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Singleton]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Azure]]></category>
		<category><![CDATA[SQL Server Compact]]></category>
		<category><![CDATA[SQLCE]]></category>
		<category><![CDATA[Table]]></category>
		<category><![CDATA[Visual Studio 2010]]></category>
		<category><![CDATA[WCF]]></category>
		<category><![CDATA[Windows Azure]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[XmlSerializer]]></category>

		<guid isPermaLink="false">http://robtiffany.com/windows-phone-7/windows-phone-7-line-of-business-app-dev-improving-the-in-memory-database</guid>
		<description><![CDATA[About a month ago, I wrote an article intended to help you fill some of the gaps left by the missing SQL Server Compact database.&#160; Since your Windows Phone 7 Silverlight app is consuming an ObservableCollection of objects streaming down &#8230; <a href="http://robtiffany.com/windows-phone-7-line-of-business-app-dev-improving-the-in-memory-database/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>About a month ago, I wrote an article intended to help you fill some of the gaps left by the missing <strong>SQL Server Compact</strong> database.&#160; Since your <strong>Windows Phone 7 Silverlight</strong> app is consuming an <strong>ObservableCollection</strong> of objects streaming down from <strong>Windows Azure</strong> and <strong>SQL Azure</strong>, it makes sense to organize those objects in a database-like format that’s easy to work with.&#160; If you’ve ever worked with <strong>Remote Data Access (RDA)</strong> in the past, the notion of <strong>pre-fetching</strong> multiple tables to work with locally should look familiar.&#160; </p>
<p>In this case, each <strong>ObservableCollection</strong> represents a table, each object represents a row, and each object property represents a column.&#160; I had you create a <strong>Singleton</strong> class to hold all these objects in memory to serve as the database.&#160; The fact that Silverlight supports <strong>Language Integrated Query (LINQ)</strong> means that you can use <strong>SQL-like statements</strong> to work with the multiple, ObservableCollections of objects.&#160; </p>
<p>If you’re wondering why I have you cache everything in memory in a Singleton, there’s a few reasons.&#160; For starters, it makes it easy to query everything with <strong>LINQ</strong> with the fastest performance possible for single and multi-table JOINs.&#160; Secondly, I don’t represent a <strong>Microsoft</strong> product group and therefore wouldn’t engineer an unsupported provider that can query subsets of serialized data from files residing in <strong>Isolated Storage</strong>.&#160; Finally, I don’t want you to accidentally find yourself with <strong>multiple instances</strong> of the same ObservableCollection when pulling data down from <strong>Azure</strong> or loading it from Isolated Storage.&#160; Forcing everything into a Singleton prevents you <strong>wasting memory</strong> or updating objects in the wrong instance of an ObservableCollection.&#160; An inconsistent database is not a good thing.&#160; Don’t worry, you can control which tables are loaded into memory.</p>
<p>So what is this article all about and what are the <strong>“improvements”</strong> I’m talking about?</p>
<p>This time around, I’m going to focus on <strong>saving</strong>, <strong>loading</strong> and <strong>deleting</strong> the <strong>serialized</strong> ObservableCollections from Isolated Storage.&#160; In that last article, I showed you how to serialize/de-serialize the ObservableCollections to and from Isolated Storage using the <strong>XmlSerializer</strong>.&#160; This made it easy for you to save each table to its own XML file which sounds pretty cool. </p>
<p>So what’s wrong with this?</p>
<p>Saving anything as <strong>XML</strong> means that you’re using the largest, most verbose form of serialization.&#160; After hearing me preach about the virtues of doing <strong>SOA</strong> with <strong>WCF REST + JSON</strong>, using the <strong>XmlSerializer</strong> probably seems out of place.&#160; Luckily, the <strong>DataContractJsonSerializer</strong> supported by <strong>Silverlight</strong> on <strong>Windows Phone 7</strong> gives you the most <strong>efficient wire protocol</strong> for data-in-transit can also be used to save those same .NET objects to Isolated Storage.&#160; So the first improvement in this article comes from shrinking the size of the tables and improving the efficiency of the serialization/de-serializing operations to Isolated Storage using out-of-the-box functionality.&#160; </p>
<p>While going from XML to JSON for your serializing might be good enough, there’s another improvement in the way you write the code that will make this much easier to implement for your own projects.&#160; A look back to the previous article reveals a <strong>tight coupling</strong> between the tables that needed to be saved/loaded and the code needed to make that happen.&#160; This meant that you would have to create a <strong>SaveTable</strong> and <strong>LoadTable</strong> method for each table that you wanted to retrieve from <strong>Azure</strong>.&#160; The new code you’re about to see is <strong>generic</strong> and allows you to use a single SaveTable and LoadTable method even if you decide to download 100 tables.</p>
<p>Enough talk already, let’s see some code.&#160; Launch your <strong>ContosoCloud</strong> solution in <strong>Visual Studio</strong> and open <strong>Database.cs</strong>.&#160; I want you to overwrite the existing code with the code shown below:</p>
<p><font size="1"><strong>using System;       <br />using System.Net;        <br />using System.Windows;        <br />using System.Collections.Generic;        <br />using System.Collections.ObjectModel;        <br />using System.IO.IsolatedStorage;        <br />using System.Runtime.Serialization.Json;</strong></font></p>
<p><font size="1"><strong>namespace ContosoPhone       <br />{        <br />&#160;&#160;&#160; sealed class Database        <br />&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; //Declare Instance        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; private static readonly Database instance = new Database();</strong></font></p>
<p><font size="1"><strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160; //Private Constructor       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; private Database() { }</strong></font></p>
<p><font size="1"><strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160; //The entry point into this Database       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public static Database Instance        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; get        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return instance;        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</strong></font></p>
<p><font size="1"><strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160; //Serialize ObservableCollection to JSON in Isolated Storage       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public void SaveTable&lt;T&gt;(T tableToSave, string tableName)        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (tableToSave != null)        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; using (IsolatedStorageFileStream stream = store.CreateFile(tableName + &quot;.txt&quot;))        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; serializer.WriteObject(stream, tableToSave);        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; else        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; throw new Exception(&quot;Table is empty&quot;);        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</strong></font></p>
<p><font size="1"><strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160; //Deserialize ObservableCollection from JSON in Isolated Storage       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public T LoadTable&lt;T&gt;(T tableToLoad, string tableName)        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (store.FileExists(tableName + &quot;.txt&quot;))        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; using (IsolatedStorageFileStream stream = store.OpenFile(tableName + &quot;.txt&quot;, System.IO.FileMode.Open))        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return (T)serializer.ReadObject(stream);        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; else        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; throw new Exception(&quot;Table not found&quot;);        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</strong></font></p>
<p><font size="1"><strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160; //Delete ObservableCollection from Isolated Storage       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public void DropTable(string tableName)        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (store.FileExists(tableName + &quot;.txt&quot;))        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; store.DeleteFile(tableName + &quot;.txt&quot;);        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; else        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; throw new Exception(&quot;Table not found&quot;);        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</strong></font></p>
<p><font size="1"><strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; //Declare Private Table Variables        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; private ObservableCollection&lt;Customer&gt; customerTable = null;</strong></font></p>
<p><font size="1"><strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160; //Customer Table       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; public ObservableCollection&lt;Customer&gt; Customers        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; get { return customerTable; }        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; set { customerTable = value; }        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }        <br />&#160;&#160;&#160; }        <br />}        <br /></strong></font></p>
<p>&#160;</p>
<p>Looking from top to bottom, the first change you’ll notice is the new <strong>SaveTable</strong> method where you pass in the desired <strong>ObservableCollection</strong> and <strong>table name</strong> in order to serialize it as <strong>JSON</strong> using the <strong>DataContractJsonSerializer</strong>.&#160; The next method down the list is <strong>LoadTable</strong> where you pass in the same parameters as <strong>SaveTable</strong> but you get back a <strong>de-serialized</strong> ObservableCollection.&#160; The last new method in the Database Singleton is <strong>DropTable</strong> which simply <strong>deletes</strong> the serialized table from Isolated Storage if you don’t need it anymore.</p>
<p>So how do you call this code?</p>
<p>Bring up <strong>MainPage.xaml.cs</strong>, and find the click event for <strong>Save button</strong>.&#160; Delete the existing <strong>XmlSerializer</strong> code and replace it with the following:</p>
<p><font size="1"><strong>try       <br />{        <br />&#160;&#160;&#160; Database.Instance.SaveTable&lt;ObservableCollection&lt;Customer&gt;&gt;(Database.Instance.Customers, &quot;Customers&quot;);        <br />}        <br />catch (Exception ex)        <br />{        <br />&#160;&#160;&#160; MessageBox.Show(ex.Message);        <br />}</strong></font></p>
<p>The code above shows you how to call the <strong>SaveTable</strong> method in the Singleton with the appropriate syntax to pass in the ObservableCollection type as well as actual ObservableCollection value and name.</p>
<p>Now find the click event for the <strong>Load button</strong>, delete the existing code and paste in the following:</p>
<p><font size="1"><strong>try       <br />{        <br />&#160;&#160;&#160; Database.Instance.Customers = Database.Instance.LoadTable&lt;ObservableCollection&lt;Customer&gt;&gt;(Database.Instance.Customers, &quot;Customers&quot;);        <br />}        <br />catch (Exception ex)        <br />{        <br />&#160;&#160;&#160; MessageBox.Show(ex.Message);        <br />}</strong></font></p>
<p>This code looks pretty much the same as the <strong>SaveTable</strong> code except that you set <strong>Database.Instance.Customers</strong> equal to the return value from the method.&#160; For completeness sake, drop another button on <strong>MainPage.xaml</strong> and call it <strong>Drop</strong>.&#160; In its click event, paste in the following code:</p>
<p><font size="1"><strong>try       <br />{        <br />&#160;&#160;&#160; Database.Instance.DropTable(&quot;Customers&quot;);        <br />}        <br />catch (Exception ex)        <br />{        <br />&#160;&#160;&#160; MessageBox.Show(ex.Message);        <br />}</strong></font></p>
<p>For this code, just pass in the name of the table you want to delete from Isolated Storage and it’s gone.</p>
<p>It’s time to hit F5 so you can see how things behave.</p>
<p><a href="http://robtiffany.com/wp-content/uploads/2010/11/phone7.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="phone7" border="0" alt="phone7" src="http://robtiffany.com/wp-content/uploads/2010/11/phone7_thumb.png" width="258" height="484" /></a></p>
<p>When your app comes to life in the emulator, I want you to exercise the system by <strong>Getting</strong>, <strong>Adding</strong>, <strong>Updating</strong> and <strong>Deleting</strong> Customers.&#160; In between, I want you to tap the Save button,<strong> close the app</strong>, reload the app and tap the Load button and then View Customers to ensure you’re seeing the list of Customers you expect.&#160; Keep in mind that when you Save, you <strong>overwrite the previously saved table</strong>.&#160; Likewise, when you Load, you <strong>overwrite the current in-memory ObservableCollection</strong>.&#160; Additionally, Saving, Loading, and Dropping tables that don’t exist should throw an appropriate error message.</p>
<p>So what’s the big takeaway for these tweaks I’ve made to the in-memory database?</p>
<p>While switching serialization from <strong>XML</strong> to <strong>JSON</strong> is a great improvement in size and efficiency, I truly believe that making the SaveTable and LoadTable methods <strong>generic</strong> and <strong>reusable</strong> will <strong>boost developer productivity</strong>.&#160; The new ease with which you can Save and Load 1, 10 or even 1,000 tables makes this more attractive to mobile developers that need to work with local data.</p>
<p>So where do we go from here?</p>
<p>You now have some of the basic elements of a database on <strong>Windows Phone 7</strong>.&#160; You don’t have <strong>ACID</strong> support, <strong>indexes</strong>, <strong>stored procedures</strong> or <strong>triggers</strong> but you have a foundation to build on.&#160; So what should be built next?&#160; </p>
<p>To help ensure <strong>database consistency</strong>, I would add an <strong>AutoFlush</strong> feature next.&#160; <strong>SQL Server Compact</strong> flushes its data to disk every 10 seconds and there’s nothing to prevent you from using the SaveTable method to do the same.&#160; A timer set to fire at a user-specified interval that <strong>iterates</strong> through all the ObservableCollections and saves them will help keep your data safe from <strong>battery loss</strong> and unforeseen system failures.&#160; The fact that your app can be <strong>tombstoned</strong> at any moment when a user taps the Back button makes an AutoFlush feature even more important.</p>
<p>Anything else?</p>
<p>At the beginning of this article I mentioned <strong>RDA</strong> which is a simple form of data synchronization.&#160; It’s simple because it only tracks changes on the client but not the server.&#160; To find out what’s new or changed on the server, RDA requires local tables on the device to be dropped and then re-downloaded from SQL Server.&#160; With the system I’ve built and described throughout this series of articles, we already have this brute force functionality.&#160; So what’s missing is <strong>client-side change tracking</strong>.&#160; To do this, I would need to add code that fires during INSERTS, UPDATES, and DELETES and then writes the appropriate information to local tracking tables.&#160; To push those changes back to <strong>SQL Azure</strong>, appropriate code would need to call <strong>WCF REST + JSON</strong> Services that execute <strong>DML</strong> code on <strong>Windows Azure</strong>.</p>
<p>I hope with the improvements I’ve made to the in-memory database in this article, you’ll feel even more empowered to build <strong>occasionally-connected</strong> Windows Phone 7 solutions for consumers and the enterprise.</p>
<p>Keep coding!</p>
<p>-Rob</p>
]]></content:encoded>
			<wfw:commentRss>http://robtiffany.com/windows-phone-7-line-of-business-app-dev-improving-the-in-memory-database/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Interview with Rob @ Tech Ed Europe 2009</title>
		<link>http://robtiffany.com/interview-with-rob-tech-ed-europe-2009/</link>
		<comments>http://robtiffany.com/interview-with-rob-tech-ed-europe-2009/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 20:45:42 +0000</pubDate>
		<dc:creator>Rob Tiffany</dc:creator>
				<category><![CDATA[Mobile Enterprise Application Platform]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[.NET Compact Framework]]></category>
		<category><![CDATA[Adapter]]></category>
		<category><![CDATA[Application Management]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Gartner]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[Integration]]></category>
		<category><![CDATA[MEAP]]></category>
		<category><![CDATA[Merge Replication]]></category>
		<category><![CDATA[Mobile Middleware]]></category>
		<category><![CDATA[Reverse Proxy]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server Business Intelligence Development Studio]]></category>
		<category><![CDATA[SQL Server Compact]]></category>
		<category><![CDATA[SSCE]]></category>
		<category><![CDATA[SSIS]]></category>
		<category><![CDATA[Sync]]></category>
		<category><![CDATA[Synchronize]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[Windows Mobile]]></category>
		<category><![CDATA[Windows phones]]></category>

		<guid isPermaLink="false">http://robtiffany.com/?p=49</guid>
		<description><![CDATA[Check out the interview I did with David Goon at Tech Ed Europe 2009 in Berlin.  I discuss Microsoft&#8217;s Mobile Enterprise Application Platform and talk about how it aligns with Gartner&#8217;s MEAP critical capabilities and how it can save money for companies. &#8230; <a href="http://robtiffany.com/interview-with-rob-tech-ed-europe-2009/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Check out the interview I did with David Goon at Tech Ed Europe 2009 in Berlin.  I discuss Microsoft&#8217;s Mobile Enterprise Application Platform and talk about how it aligns with Gartner&#8217;s MEAP critical capabilities and how it can save money for companies.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="320" height="180" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.facebook.com/v/241564376017" /><embed type="application/x-shockwave-flash" width="320" height="180" src="http://www.facebook.com/v/241564376017" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>With the tidal wave of mobile and wireless technologies sweeping across both the consumer and enterprise landscapes, I believe MEAP offerings give us a glimpse of a new standard for designing all future infrastructures.</p>
<p>-Rob</p>
]]></content:encoded>
			<wfw:commentRss>http://robtiffany.com/interview-with-rob-tech-ed-europe-2009/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

