<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6070382805242147283</id><updated>2011-12-09T22:55:09.919+11:00</updated><category term='CRM 2011'/><category term='Windows 2008 Server'/><category term='Team Foundation Server'/><category term='Microsoft CRM'/><category term='Linq to SQL'/><category term='Hyper-V'/><category term='Microsoft CRM 4.0'/><category term='Windows Service'/><category term='Java'/><category term='Password Policy'/><category term='Linq to SQL Entity Base'/><category term='Microsoft CRM 2011'/><category term='Javscript'/><category term='.NET'/><category term='Silverlight'/><title type='text'>Matt's .Net Blog for Software Developers</title><subtitle type='html'>The good, the bad and the ugly of software development on the .NET platform.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>45</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-1131963907963166652</id><published>2011-08-14T18:59:00.006+10:00</published><updated>2011-08-14T19:20:35.523+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft CRM'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft CRM 2011'/><title type='text'>How to break linked reports in CRM 2011</title><content type='html'>&lt;em&gt;&lt;blockquote&gt;Crm Exception: Message: Linked reports cannot be downloaded, ErrorCode: -2147220970&lt;/blockquote&gt;&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;If you are finding that linked reports are failing to display in CRM 2011, and you get the old "Unexpected Error" message and when you look at CRM's tracing you find the message above, check that you have not removed the "Report Type" field from any of the Reports views.&lt;br /&gt;&lt;br /&gt;It seems that the CRM team are using this column to launch linked reports and without it when a report is launched will go to link to download.aspx instead of the specified page.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-1131963907963166652?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/1131963907963166652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=1131963907963166652' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/1131963907963166652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/1131963907963166652'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2011/08/how-to-break-linked-reports-in-crm-2011.html' title='How to break linked reports in CRM 2011'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-3227231726775243349</id><published>2011-07-30T18:23:00.004+10:00</published><updated>2011-07-30T18:48:06.784+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CRM 2011'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><title type='text'>CRM 2011, Silverlight and Refresh Issue</title><content type='html'>When I added a Silverlight 4.0 application to a CRM form, I discovered a problem when you referesh the page in the browser. The issue is that on refresh the Silverlight application is ready before the Xrm.Page.ui is loaded and ready to access from Silverlight.&lt;br /&gt;&lt;br /&gt;This was a major problem for me as I needed to know what CRM Form Type was, which is done by invoking the "getFormType" method on the Xrm.Page.iu property of the form.&lt;br /&gt;&lt;br /&gt;After trying a number of things, I found the only way to reliably access the form type was to attempt to keep accessing form type until a value was succesfully returned.&lt;br /&gt;&lt;br /&gt;So, for those interested, here's a snipped from my silverlight application which might help you:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;            // To get around problem that form may not yet be full loaded&lt;br /&gt;            // and so javascript can't be invoked yet, keep trying until&lt;br /&gt;            // we can get the form type, waiting a second between each try.&lt;br /&gt;            DispatcherTimer timer = new DispatcherTimer();&lt;br /&gt;            timer.Interval = new TimeSpan(0, 0, 1);&lt;br /&gt;            timer.Tick += (object s, EventArgs args) =&amp;gt;&lt;br /&gt;            {&lt;br /&gt;                int? formType = null;&lt;br /&gt;&lt;br /&gt;                // Attempt to get the Form Type&lt;br /&gt;                try { formType = CrmUtility.GetFormType(); }&lt;br /&gt;                catch { }&lt;br /&gt;&lt;br /&gt;                if (formType != null)&lt;br /&gt;                {&lt;br /&gt;                    timer.Stop();&lt;br /&gt;&lt;br /&gt;                    if (formType == 2) // 2 = Update&lt;br /&gt;                    {&lt;br /&gt;                        // ... Do work here ...&lt;br /&gt;                    }                    &lt;br /&gt;                }&lt;br /&gt;            };&lt;br /&gt;            timer.Start();&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note that all GetFormType() method does is find the Xrm.Page.ui property and then calls .Invoke("getFormType") to get the current Form Mode from the regular Crm Javascript methods.&lt;br /&gt;&lt;br /&gt;Also, you would expect this code to go somewhere in the initialization of your Silverlight Application.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-3227231726775243349?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/3227231726775243349/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=3227231726775243349' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/3227231726775243349'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/3227231726775243349'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2011/07/crm-2011-silverlight-and-refresh-issue.html' title='CRM 2011, Silverlight and Refresh Issue'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-537509408602834161</id><published>2011-06-05T21:00:00.005+10:00</published><updated>2011-06-05T21:05:20.061+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CRM 2011'/><title type='text'>CRM 2011 : The given plugin assembly source type is not supported for isolated plugin assemblies.</title><content type='html'>&lt;span style="font-weight:bold;"&gt;&lt;div&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;The given plugin assembly source type is not supported for isolated plugin assemblies.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you are getting this error message, it's because you are trying to register an assembly as sand boxed but have it's location set to disk or GAC.  This is not an allowed combination, instead if you need it to be sand boxed set the storage location to the database.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-537509408602834161?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/537509408602834161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=537509408602834161' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/537509408602834161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/537509408602834161'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2011/06/crm-2011-given-plugin-assembly-source.html' title='CRM 2011 : The given plugin assembly source type is not supported for isolated plugin assemblies.'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-2457254750964613755</id><published>2011-04-09T11:02:00.003+10:00</published><updated>2011-04-09T11:22:40.243+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft CRM'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft CRM 2011'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft CRM 4.0'/><title type='text'>Running CRM 4.0 App on CRM 2011 Server</title><content type='html'>I came accross an issue running software on a CRM 2011 server that was designed for CRM 4.0. There error that was reported is as follows:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Could not load file or assembly 'Microsoft.Crm.Sdk, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I was quite surprised to get this after being told by the CRM 2011 SDK that software targeting CRM 4.0 should still be compatible.&lt;br /&gt;&lt;br /&gt;After lookin at &lt;a href="https://community.dynamics.com/product/crm/crmtechnical/b/crmdavidjennaway/archive/2011/02/16/using-crm-4-0-assemblies-on-a-crm-2011-server.aspx"&gt;this link&lt;/a&gt; it seems that the CRM 2011 installation is forwarding any reference to the CRM 4.0 assembly to the CRM 2011 assembly via a publisher policy - which aren't 100% compatible.&lt;br /&gt;&lt;br /&gt;Although you can get around it by modifying your applications config file (which is described in the link above), this issue can also be fixed now by applying &lt;a href="http://support.microsoft.com/kb/2466084"&gt;Rollup Pack 1&lt;/a&gt; as indicated in the notes for the Rollup Pack:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;The Microsoft.Crm.Sdk.dll file has an incorrect publisher policy registered in the global assembly cache (GAC). Therefore, when you use an application that is built with this dependency, the application fails in Microsoft Dynamics CRM 2011 Server.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Good to know if you intend to run software that was designed for CRM 4.0 on a CRM 2011 server.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-2457254750964613755?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/2457254750964613755/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=2457254750964613755' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/2457254750964613755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/2457254750964613755'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2011/04/running-crm-40-app-on-crm-2011-server.html' title='Running CRM 4.0 App on CRM 2011 Server'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-3317223142736552906</id><published>2011-02-28T21:35:00.014+11:00</published><updated>2011-03-10T23:00:06.097+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows 2008 Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Password Policy'/><title type='text'>Windows 2008 Server Domain Controller - Change Password Settings</title><content type='html'>Having built a lot of Virtual Development Environments with Windows server 2008 and CRM, one thing that I always have to lookup is how to disable the annoying password settings so that the password doesn't have to be reset every 42 days.  &lt;br /&gt;&lt;br /&gt;Setting this is not so straight forward, so below are the instructions on how to do this successfully on a Windows 2008 Server that is setup as a domain controller.&lt;br /&gt;&lt;br /&gt;1. Start --&gt; All Programs --&gt; Group Policy Management&lt;br /&gt;&lt;br /&gt;2. Expand Forest --&gt; Domains --&gt; (your domain) &lt;br /&gt;&lt;br /&gt;3. Right click on Default Domain Policy and Select "edit..."&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-3tRc2xUhNOc/TWuA2iZMm5I/AAAAAAAAACk/1IU4ktwoK2g/s1600/Capture1.PNG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 376px; height: 316px;" src="http://4.bp.blogspot.com/-3tRc2xUhNOc/TWuA2iZMm5I/AAAAAAAAACk/1IU4ktwoK2g/s400/Capture1.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5578694237862271890" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;4. Expand Policies --&gt; Windows Settings --&gt; Security Settings --&gt; Account Policies&lt;br /&gt;&lt;br /&gt;5. Inside Password Polcies you will find all the relavent password settings.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-6CYeHVNOWVk/TWuA2xCLHfI/AAAAAAAAACs/4xNgKmU-_sI/s1600/Capture2.PNG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 164px;" src="http://4.bp.blogspot.com/-6CYeHVNOWVk/TWuA2xCLHfI/AAAAAAAAACs/4xNgKmU-_sI/s400/Capture2.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5578694241792237042" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;6. Setting Maximum password age to 0 will disable password expiry.&lt;br /&gt;&lt;br /&gt;7. Exit out and in the command line run "gpupdate.exe"&lt;br /&gt;&lt;br /&gt;Now you should be good to go :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-3317223142736552906?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/3317223142736552906/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=3317223142736552906' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/3317223142736552906'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/3317223142736552906'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2011/02/windows-2008-server-domain-controller.html' title='Windows 2008 Server Domain Controller - Change Password Settings'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-3tRc2xUhNOc/TWuA2iZMm5I/AAAAAAAAACk/1IU4ktwoK2g/s72-c/Capture1.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-2437903901173732823</id><published>2011-02-14T14:59:00.004+11:00</published><updated>2011-02-14T15:16:11.853+11:00</updated><title type='text'>CRM 4.0 SiteMap.xml and "Object doesn't support this property or method" error.</title><content type='html'>Today I came across an unusual error where a custom SiteMap SubArea (mapping to a URL) entry was causing an "Object doesn't support this property or method" when the user was navigating to the other subareas in the sitemap configuration in the same page.&lt;br /&gt;&lt;br /&gt;Eventually I found out the SubArea's parent Group had the same ID, and this was causing the issue.  Simply changing the Id's fixed the error. (Would have been nice to have an error that was raised somewhere which indicated this, but such is life.)&lt;br /&gt;&lt;br /&gt;I hope this saves someone some agony out there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-2437903901173732823?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/2437903901173732823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=2437903901173732823' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/2437903901173732823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/2437903901173732823'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2011/02/crm-40-sitemapxml-and-object-doesnt.html' title='CRM 4.0 SiteMap.xml and &quot;Object doesn&apos;t support this property or method&quot; error.'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-8651899253275439886</id><published>2011-01-17T14:55:00.004+11:00</published><updated>2011-01-17T15:12:45.173+11:00</updated><title type='text'>How to check where your CRM 4.0 Plugin is being called from</title><content type='html'>Recently, I needed to figure out if a CRM 4.0 Plugin was being called from CRM or whether it was being called from the CRM API.&lt;br /&gt;&lt;br /&gt;Luckily, the context provides this information through the context.CallerOrigin property.  You can use this to determine whether the plugin is being called by comparing the type of the property to the following types:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;if(context.CallerOrigin Is ApplicationOrigin) // It's being called from the CRM Web Application&lt;br /&gt;&lt;br /&gt;if(context.CallerOrigin Is AsyncServiceOrigin) // It's being called from the Async Process&lt;br /&gt;&lt;br /&gt;If(context.CallerOrigin Is WebServiceApiOrigin) // It's being called from external to CRM Via Web Services.&lt;blockquote&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So there you have it...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-8651899253275439886?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/8651899253275439886/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=8651899253275439886' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/8651899253275439886'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/8651899253275439886'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2011/01/how-to-check-where-your-crm-40-plugin.html' title='How to check where your CRM 4.0 Plugin is being called from'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-2434179988837046678</id><published>2010-09-18T08:58:00.004+10:00</published><updated>2010-09-18T09:12:24.649+10:00</updated><title type='text'>Enumerable Select Magic in C#</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;I'd always wanted to toy with the "Select" extension method that lives in the &lt;strong&gt;System.Linq&lt;/strong&gt; namespace, and today I found a great opportunity to use it.&lt;br /&gt;&lt;br /&gt;I had to calculate the number of working days between two dates (e.g. no weekends), and to do this I used a mix of the Range method on the Enumerable class and the select method, plus a list of the weekdays.  The result is below.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;public int WorkingDays(DateTime startDate, DateTime endDate)&lt;br /&gt;{&lt;br /&gt;    int totalDays = endDate.Subtract(startDate).Days + 1;&lt;br /&gt;            &lt;br /&gt;    List&amp;lt;DayOfWeek&amp;gt; businessDays = new List&amp;lt;DayOfWeek&amp;gt;() &lt;br /&gt;                                    { System.DayOfWeek.Monday, System.DayOfWeek.Tuesday, System.DayOfWeek.Wednesday, &lt;br /&gt;                                        System.DayOfWeek.Thursday, System.DayOfWeek.Friday };&lt;br /&gt;&lt;br /&gt;    return Enumerable.Range(0, totalDays)&lt;br /&gt;            .Select( d =&amp;gt; startDate.AddDays(d))&lt;br /&gt;            .Where( wd =&amp;gt; businessDays.Contains(wd.DayOfWeek)).Count();&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt; &lt;/p&gt;&lt;p&gt;Anyway, I think it's a great basic example of how to use the select method, so I thought I'd share it.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-2434179988837046678?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/2434179988837046678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=2434179988837046678' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/2434179988837046678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/2434179988837046678'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2010/09/enumerable-select-magic-in-c.html' title='Enumerable Select Magic in C#'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-758688301982104246</id><published>2010-06-19T12:11:00.006+10:00</published><updated>2010-06-19T12:53:49.912+10:00</updated><title type='text'>Visual Studio 2010, Web.Config Transformations and the Broken Bits</title><content type='html'>&lt;div&gt;For those of you who are deploying web applications using the new Visual Studio 2010 features in the RTM version, keep these issues in mind when you are using the new web.config transformation features:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;xdt:transform="Replace" attributes don't work properly&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you are are using application settings with a .net Project, you'll find that the XML will actually stored the value in an element rather than as a attribute.  When you try to apply the "Replace" tranform on this, you'll find that the result after publishing changes the value from this&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;&amp;lt;value&amp;gt;mystringvalue&amp;lt;/value&amp;gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;to this&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;&amp;lt;value&amp;gt;mystringvalue&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&amp;lt;/value&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;value&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Unfortunately, this actually adds the spaces to the end of your value, and the only way round it at the moment is to actually modify your code with a string.Trim() function to ignore the additional spaces.  This probably also occurs anywhere you have an element representing a value rather than an attribute representing a value in your web.config.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For more information, see &lt;a href="http://connect.microsoft.com/VisualStudio/feedback/details/544183/web-config-transform-writes-extra-line-break-spaces-to-values-elements-under-applicationsettings-section"&gt;here&lt;/a&gt; and &lt;a href="http://connect.microsoft.com/VisualStudio/feedback/details/568073/web-config-transform-adds-tabs-and-carriage-returns"&gt;here&lt;/a&gt; for more information on the issue.&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal; "&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;xdt:transform="XSLT" does not exist and is not valid although documented!&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal; "&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;When you have a look at the documentation around the web.config transform, you'll find that there's this excellent feature where you can have a standard XSLT transform.  Well, it looks like it was accidentally omitted from the final release of Visual Studio 2010, because when you go to use it, the syntax is not recognized at all, in fact it gives you this message:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"Could not resolve 'XSLT' as a type of Transform".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You can find more information about the issue &lt;a href="http://connect.microsoft.com/VisualStudio/feedback/details/567969/in-a-config-transform-the-attribute-xdt-transform-xslt-is-not-recognised"&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Cheers&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Matt.&lt;/div&gt;&lt;/value&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-758688301982104246?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/758688301982104246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=758688301982104246' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/758688301982104246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/758688301982104246'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2010/06/visual-studio-2010-webconfig.html' title='Visual Studio 2010, Web.Config Transformations and the Broken Bits'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-6017337166019418102</id><published>2010-06-12T22:24:00.005+10:00</published><updated>2010-06-12T22:39:23.685+10:00</updated><title type='text'>CRM 4.0 QUERY T4 Template</title><content type='html'>Hi Everyone,&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I've finally got around to publishing some work I've done recently which leverages LINQ to SQL, T4 Templates and the CRM 4.0 API to create a data access layer to CRM.&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Originally I started write a Query provider for LINQ, but found it to be an extreme amount of work - and decided instead to return to old faithful - LINQ to SQL - which I have a good grounding in.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Recently, Microsoft have added a LINQ to CRM query provider to the SDK (Version 4.0.12) so you should check that out.  If it doesn't suit you, here's an alternative.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;Features&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Uses LINQ to SQL for Querying, meaning that you have the complete power of LINQ to SQL at your disposal&lt;/li&gt;&lt;li&gt;Database Queries do not go through CRM API, so they are potentially faster&lt;/li&gt;&lt;li&gt;Uses the CRM 4.0 API for CUD (Create, Update, Delete) operations - so data integrity is maintained.&lt;/li&gt;&lt;li&gt;Can generate only selected entities, rather than the entire CRM Entity list.&lt;/li&gt;&lt;li&gt;Works with WCF RIA services and any other technology that takes advantage of LINQ to SQL&lt;/li&gt;&lt;li&gt;You don't need to Leave the Visual Studio Environment, T4 generation is done within Visual Studio.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Anyway, if you have the time or the need, check it out &lt;a href="http://crmquery.codeplex.com/"&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Cheers&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Matt&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-6017337166019418102?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://crmquery.codeplex.com/' title='CRM 4.0 QUERY T4 Template'/><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/6017337166019418102/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=6017337166019418102' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/6017337166019418102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/6017337166019418102'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2010/06/crm-40-query-t4-template.html' title='CRM 4.0 QUERY T4 Template'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-2964019729866962423</id><published>2010-05-07T09:32:00.002+10:00</published><updated>2010-05-07T09:36:43.661+10:00</updated><title type='text'>CRM 4.0.12 SDK Release</title><content type='html'>Microsoft have just released the Microsoft CRM 4.0.12 SDK, which has a number of new developer features.&lt;br /&gt;&lt;br /&gt;I'm still going through them, but I'm liking what I see.&lt;br /&gt;&lt;br /&gt;One that stood out to me is that they now have a CRM 4.0 LINQ provider included! Yay!&lt;br /&gt;&lt;br /&gt;To download the SDK and check it out, find it here:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=82E632A7-FAF9-41E0-8EC1-A2662AAE9DFB&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyID=82E632A7-FAF9-41E0-8EC1-A2662AAE9DFB&amp;amp;displaylang=en&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Cheers&lt;br /&gt;&lt;br /&gt;Matt&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-2964019729866962423?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.microsoft.com/downloads/details.aspx?FamilyID=82E632A7-FAF9-41E0-8EC1-A2662AAE9DFB&amp;displaylang=en' title='CRM 4.0.12 SDK Release'/><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/2964019729866962423/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=2964019729866962423' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/2964019729866962423'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/2964019729866962423'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2010/05/crm-4012-sdk-release.html' title='CRM 4.0.12 SDK Release'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-2913233774592550031</id><published>2010-04-19T16:11:00.002+10:00</published><updated>2010-04-19T16:16:26.433+10:00</updated><title type='text'>LINQ to SQL Entity Base Version 1.2 Final</title><content type='html'>Hi everyone,&lt;br /&gt;&lt;br /&gt;I've published the latest version of the Entity Base (Version 1.2) on Codeplex.&lt;br /&gt;&lt;br /&gt;There were no source code changes since Version 1.2 Beta, although if you were previously on 1.1 there are a few bug fixes that you may be interested in.&lt;br /&gt;&lt;br /&gt;You can find the release here:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://linq2sqleb.codeplex.com/releases/view/43763"&gt;http://linq2sqleb.codeplex.com/releases/view/43763&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Cheers&lt;br /&gt;&lt;br /&gt;Matt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-2913233774592550031?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/2913233774592550031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=2913233774592550031' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/2913233774592550031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/2913233774592550031'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2010/04/linq-to-sql-entity-base-version-12.html' title='LINQ to SQL Entity Base Version 1.2 Final'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-2170440584215916619</id><published>2010-03-13T12:41:00.005+11:00</published><updated>2010-03-13T13:05:28.837+11:00</updated><title type='text'>Windows 7 HomeGroup Issue - possible solution</title><content type='html'>I had been trying to setup my network at home with a home group, so that all documents, printers, movies, etc... where available easily from any PC in the house.&lt;br /&gt;&lt;br /&gt;Although I could join the homegroup with no issue, none of the computers could see the shares on the other, nor the default profile folders (documents, pictures etc..) and when I tried to view the full network map (found under the "Network and Sharing Center"), it was showing a strange network topology that didn't look anything like what I had, and didn't show the other machines properly.&lt;br /&gt;&lt;br /&gt;Everything was configured correctly - but it just didn't work. How Frustrating.&lt;br /&gt;&lt;br /&gt;After fiddling a good deal and looking up a few solutions in various forums, I almost gave up when I though i might check the configuration of the computer name, and found the setting below in the screenshot which I don't recall seeing before, but there it was under the System Settings --&gt;Change Settings--&gt;Network ID.&lt;br /&gt;&lt;br /&gt;Changing the value from "This computer is part of a busines network etc..." to "This is a home computer; it's not part etc.." fixed the issue.&lt;br /&gt;&lt;br /&gt;The Network map was now correct (infact I was impressed, it was spot on - even with multiple routers!), and so I repeated these steps on each computer in the network which also fixed their maps as well.&lt;br /&gt;&lt;br /&gt;I then removed all computers from the home group, create a new home group and joined all the PC's again to it. Once I did this, the home group was up and running. I have no idea why this works, and ever after re-booting it's back to the "business network" option, but all I can say is it solved my issue and now I can enjoy the fruits of Windows 7.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_nrt4ht8y-jk/S5rul9_SGII/AAAAAAAAABU/VE9WUtwFF20/s1600-h/Capture.JPG"&gt;&lt;img style="WIDTH: 400px; HEIGHT: 191px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5447929035320596610" border="0" alt="" src="http://2.bp.blogspot.com/_nrt4ht8y-jk/S5rul9_SGII/AAAAAAAAABU/VE9WUtwFF20/s400/Capture.JPG" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-2170440584215916619?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/2170440584215916619/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=2170440584215916619' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/2170440584215916619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/2170440584215916619'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2010/03/windows-7-homegroup-issue-possible.html' title='Windows 7 HomeGroup Issue - possible solution'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_nrt4ht8y-jk/S5rul9_SGII/AAAAAAAAABU/VE9WUtwFF20/s72-c/Capture.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-8017682225754209791</id><published>2009-12-17T09:24:00.003+11:00</published><updated>2009-12-17T12:37:03.277+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft CRM'/><title type='text'>"Service Unavailable" message in CRM 4.0</title><content type='html'>If you are running Windows 2003 server with a CRM Installation and you get the "Service Unavailable" message, check the application pool for CRM in IIS.&lt;br /&gt;&lt;br /&gt;If it's stopped, start it again, and try going to the CRM web page again. If the CRM application pool stops again, it's likely that you've just applied patch &lt;a href="http://support.microsoft.com/kb/973917"&gt;KB973917&lt;/a&gt;, try removing this patch from the server, reboot, this should fix the problem.&lt;br /&gt;&lt;br /&gt;Cheers&lt;br /&gt;&lt;br /&gt;Matt&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-8017682225754209791?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/8017682225754209791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=8017682225754209791' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/8017682225754209791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/8017682225754209791'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2009/12/service-unavailable-message.html' title='&quot;Service Unavailable&quot; message in CRM 4.0'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-4900038732412062479</id><published>2009-12-03T07:24:00.003+11:00</published><updated>2009-12-03T07:32:40.340+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linq to SQL Entity Base'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq to SQL'/><title type='text'>LINQ to SQL Entity Base - Version 1.2 Beta</title><content type='html'>&lt;p&gt;Hi everyone,&lt;br /&gt;&lt;br /&gt;I've released a beta of the LINQ 2 SQL Entity Base - included in it is the following changes since the V1.1 final:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Bug Fix:&lt;/strong&gt; If the entity's state is "New", LINQ to SQL Tries to attach an FK references as "New" as well - even though this was unintended. Fixed it so it does not try and insert FK referenced entities when adding a new object. Thanks Mark &amp;amp; Stephan for finding/fixing the issue&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Bug Fix:&lt;/strong&gt; If the onModifyKeepOriginal parameter on SetAsChangeTrackingRoot() is set to true and an object is detached from a collection (i.e. x.remove(y)), the object was not being attached properly to the data context when SynchroniseWithDataContext() was called, causing an error to be thrown. Thanks Yaki for finding the issue!&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Bug Fix:&lt;/strong&gt; When EntityState == CanceNew, don't change to EntityState == Deleted when SetAsDeleteOnSubmit is called.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Feature:&lt;/strong&gt; Added ShallowCompare Method, which compares the properties of two entities and returns true if all the properties match (compare LINQ to SQL ColumnAttribute properties only).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Feature:&lt;/strong&gt; If the onModifyKeepOriginal parameter on SetAsChangeTrackingRoot() is set to true, and an object is modified (i.e. EntityState == Modified) and then modified again in a way which set's it back to be the same as property values as it's original state, the entity will now have it's EntityState set to back Original (instead of remaining as EntityState == "Modified"). &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;It can be downloaded here:&lt;/p&gt;&lt;p&gt;&lt;a href="http://linq2sqleb.codeplex.com/"&gt;http://linq2sqleb.codeplex.com&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Cheers&lt;/p&gt;&lt;p&gt;Matt.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-4900038732412062479?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/4900038732412062479/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=4900038732412062479' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/4900038732412062479'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/4900038732412062479'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2009/12/linq-to-sql-entity-base-version-12-beta.html' title='LINQ to SQL Entity Base - Version 1.2 Beta'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-426465704773264430</id><published>2009-10-27T18:29:00.006+11:00</published><updated>2009-10-27T18:34:18.526+11:00</updated><title type='text'>Address Attribute Length Fun in CRM 4.0</title><content type='html'>When you extend the length of Address attribute on a Contact or Account, this does not actually extend the length of the attribute in the database auto-magically only the length of the data that can be entered on the UI.&lt;br /&gt;&lt;br /&gt;The address details are not stored agains the customer, they are stored in a seperate entity called "Address".&lt;br /&gt;&lt;br /&gt;In order to extend the address you need to update the "Address" attribute too.&lt;br /&gt;&lt;br /&gt;See this KB for more info:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://support.microsoft.com/kb/973029"&gt;http://support.microsoft.com/kb/973029&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-426465704773264430?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/426465704773264430/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=426465704773264430' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/426465704773264430'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/426465704773264430'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2009/10/address-attribute-length-fun.html' title='Address Attribute Length Fun in CRM 4.0'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-1796648252160480966</id><published>2009-10-27T17:41:00.007+11:00</published><updated>2009-11-20T07:46:46.074+11:00</updated><title type='text'>Data Migration Manager Troubles with CRM 4.0</title><content type='html'>Today I spent quite a lot of time trying to figure out why the data migration manager would not let me sign in.&lt;br /&gt;&lt;br /&gt;I'd just installed Rollup Pack 7, and noticed that there was no Data Migration Manager Update available in Rollup Pack 7, so I installed Rollup Pack 6's version of this update.&lt;br /&gt;&lt;br /&gt;Everytime I tried to login, it would complain that ...&lt;br /&gt;&lt;br /&gt;"You must have the System Administrator Security Role to use this Tool".&lt;br /&gt;&lt;br /&gt;I was puzzled, I checked multiple times to make sure that the user I put in during the install was correct, I searched the web - but this error had not be reported anywhere by anyone.&lt;br /&gt;&lt;br /&gt;Finally I decided to remove the Rollup Pack 6 update (only the update) for the Data Migration Manager, and to my surprise this worked! Infact I was even more surprised to find that it did not complain that there were updates available for it (which it usually does...).&lt;br /&gt;&lt;br /&gt;Anyway, I re-installed the Data Migration Manager Rollup 6 Update and it now works.&lt;br /&gt;&lt;br /&gt;So the fix is to Re-install if you get this error message.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;[UPDATE] Came into work this morning, and a member of my team had exactly the same problem on a completely different server, Wonder if there's a Data Migration Manager Rollup-7 that hasn't been upload to the MS Download Site yet?&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;[UPDATE2] There's a Rollup Pack 7 installer for the Data Migration Manager Now, however haven't tried it yet to see if it works personally, but apparently it does.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-1796648252160480966?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/1796648252160480966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=1796648252160480966' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/1796648252160480966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/1796648252160480966'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2009/10/data-migration-manager-troubles.html' title='Data Migration Manager Troubles with CRM 4.0'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-1039861809324165270</id><published>2009-09-04T17:16:00.009+10:00</published><updated>2011-08-14T19:24:01.863+10:00</updated><title type='text'>Default Organization For User is incorrect in CRM 4.0</title><content type='html'>&lt;p&gt;Occasionally you come across the situation where the default organization has been changed and some of the users are still mapped with the default to the old database. This is quite annoying and can actually point your custom aspx pages to the wrong organization.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;To fix this issue, I've written a SQL Server script which basically does the following:&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Finds the specified organization in the MSCRM_CONFIG database (the one that you want to be the default)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Finds the specified user ( which has the incorrect default database ) in the organization database which is intended to be the default (Based on '&amp;lt;domain&amp;gt;\&amp;lt;username&amp;gt;')&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Finds the user details in the MSCRM_CONFIG database from the specified user found in the organization database&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Updates the user record in the MSCRM_CONFIG database to have the specified default organization set.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Notes on running the script:&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Backup your MSCRM_CONFIG database first! This is unsupported by Microsoft and Me!&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;Set the Domain\Username &amp;amp; Organization Name in the section titled 'PLEASE FILL IN THE FOLLOWING'&lt;br /&gt;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;The @UserDomainName is the same as found the DomainName box in the User CRM Screen&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The @DefaultOrganization should be the name of the organization as shown in the deployment manager&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;The script is designed to be executed in the context of the organization database which you want to be the default for the specified user, please make sure that this is set to the correct database before running&lt;br /&gt;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;i.e. you can do this by using the 'Use &amp;lt;databasename&amp;gt;' command in SQL first before executing the script. &lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color:#ff0000;"&gt;UPDATE&lt;/span&gt;: You may need to restart IIS in order for the change to take place.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&lt;br /&gt;DECLARE @DefaultOrganization AS VARCHAR (100);&lt;br /&gt;&lt;br /&gt;DECLARE @DefaultOrganizationId AS VARCHAR (100);&lt;br /&gt;&lt;br /&gt;DECLARE @UserDomainName AS VARCHAR (100);&lt;br /&gt;&lt;br /&gt;DECLARE @CRMUserId AS VARCHAR (100);&lt;br /&gt;&lt;br /&gt;DECLARE @UserId AS VARCHAR (100);&lt;br /&gt;&lt;br /&gt;SET @UserDomainName = '&amp;lt;domain&amp;gt;\&amp;lt;username&amp;gt;';&lt;br /&gt;&lt;br /&gt;SET @DefaultOrganization = '&amp;lt;organizationname&amp;gt;';&lt;br /&gt;&lt;br /&gt;SELECT @DefaultOrganizationId = id&lt;br /&gt;FROM   MSCRM_CONFIG..organization&lt;br /&gt;WHERE  UniqueName = @DefaultOrganization;&lt;br /&gt;&lt;br /&gt;IF @DefaultOrganizationId IS NOT NULL&lt;br /&gt;    BEGIN&lt;br /&gt;        SELECT @CRMUserId = systemuserid&lt;br /&gt;        FROM   systemuserbase&lt;br /&gt;        WHERE  domainname = @UserDomainName;&lt;br /&gt;        IF @CRMUserId IS NOT NULL&lt;br /&gt;            BEGIN&lt;br /&gt;                SELECT @UserId = userid&lt;br /&gt;                FROM   MSCRM_CONFIG..systemuserorganizations&lt;br /&gt;                WHERE  crmuserid = @CRMUserId;&lt;br /&gt;                IF @UserId IS NOT NULL&lt;br /&gt;                    BEGIN&lt;br /&gt;                        SELECT 'BEFORE', *&lt;br /&gt;                        FROM   MSCRM_CONFIG..systemuser&lt;br /&gt;                        WHERE  id = @UserId;&lt;br /&gt;                        UPDATE  MSCRM_CONFIG..systemuser&lt;br /&gt;                            SET defaultorganizationid = @DefaultOrganizationId&lt;br /&gt;                        WHERE   id = @UserId;&lt;br /&gt;                        SELECT 'AFTER', *&lt;br /&gt;                        FROM   MSCRM_CONFIG..systemuser&lt;br /&gt;                        WHERE  id = @UserId;&lt;br /&gt;                    END&lt;br /&gt;                ELSE&lt;br /&gt;                    BEGIN&lt;br /&gt;                        PRINT 'The User was Not Found in the Organization - Please check';&lt;br /&gt;                    END&lt;br /&gt;            END&lt;br /&gt;        ELSE&lt;br /&gt;            BEGIN&lt;br /&gt;                PRINT 'The User was Not Found in CRM - Please check';&lt;br /&gt;            END&lt;br /&gt;    END&lt;br /&gt;ELSE&lt;br /&gt;    BEGIN&lt;br /&gt;        PRINT 'Default Organization Not Found - Please check';&lt;br /&gt;    END&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-1039861809324165270?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/1039861809324165270/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=1039861809324165270' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/1039861809324165270'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/1039861809324165270'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2009/09/default-organization-for-user-is.html' title='Default Organization For User is incorrect in CRM 4.0'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-9168445030651112193</id><published>2009-09-01T14:48:00.001+10:00</published><updated>2009-09-01T14:48:03.617+10:00</updated><title type='text'>Run as Different User in Windows 7</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;In windows XP, when you wanted to run as a different user you could by right-clicking and selecting "Run As", in Windows Vista this was missing – although you could use the RunAs.exe in command line to kick off an application as a different user – it was really annoying and painful to do.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Now in Windows 7, Run As is back!&lt;br /&gt;&lt;/p&gt;&lt;p&gt;To run as a different user, simply hold down shift and right click on an icon to get the "Run as different User" option.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Very useful in MS CRM for testing our roles for different user.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Matt.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt; &lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-9168445030651112193?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/9168445030651112193/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=9168445030651112193' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/9168445030651112193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/9168445030651112193'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2009/09/run-as-different-user-in-windows-7.html' title='Run as Different User in Windows 7'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-6494005112601451482</id><published>2009-08-28T11:44:00.001+10:00</published><updated>2009-08-28T11:44:12.589+10:00</updated><title type='text'>Access denied to something? – try changing your password</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;&lt;br /&gt; &lt;/p&gt;&lt;p&gt;One thing that I've found time and time again with Windows authentication is that even though you have access to something and your password is not expired – you may still received the "access denied" type response from different applications/services. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;At first you think it's some kind of issue with permissions, you try rebooting etc... But nothing works.  &lt;br /&gt;&lt;/p&gt;&lt;p&gt;In these circumstances, if you have noticed that you are being reminded to change your password when you log onto the windows server/workstation – then changing your password may be the key!&lt;br /&gt;&lt;/p&gt;&lt;p&gt;It seems that although technically your account on the domain hasn't expired - because it's due to expire this sometimes seems to be interpreted as the same thing (i.e. it considers your account expired).  Perhaps the underlying integrated security authentication that goes on behind the scenes doesn't always deal with this situation properly, and just rejects by default.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Anyway, try changing your password and see if that helps!&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Matt.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-6494005112601451482?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/6494005112601451482/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=6494005112601451482' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/6494005112601451482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/6494005112601451482'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2009/08/access-denied-to-something-try-changing.html' title='Access denied to something? – try changing your password'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-735828436482577414</id><published>2009-07-14T08:00:00.003+10:00</published><updated>2009-07-14T08:07:13.444+10:00</updated><title type='text'>Version 1.1 Final of LINQ to SQL Entity Base Released</title><content type='html'>Hi everyone,&lt;br /&gt;&lt;br /&gt;I've released the latest version of the LINQ to SQL Entity Base.  If you are unfamiliar with it, it allows you to have change tracking without having to have the DataContext object within scope.&lt;br /&gt;&lt;br /&gt;Here's the changes since Version 1.0&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;strong&gt;Improvement&lt;/strong&gt;: Implemented caching for reflected properties which should significantly speed up creation of entity instances. Thanks Johannes! &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Improvement&lt;/strong&gt;: If you delete an entity while it is in the new state (and therefore has not been submitted to the database yet), the entity will now be removed from the scope of the entity tree during the call SyncronisationWithDataContext(), and as there are no references to the entity anymore it will be garbage collected. Before this change, the object would still hang around.&lt;br /&gt; &lt;br /&gt;&lt;strong&gt;Bug Fix&lt;/strong&gt;: Issue where setting a value FK value via object reference did not result in entity being flagged as modified unless you modified another property on that entity as well.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Anyway, head on over to &lt;a href="http://linq2sqleb.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=30108"&gt;codeplex &lt;/a&gt;to check it out.&lt;br /&gt;&lt;br /&gt;Cheers&lt;br /&gt;&lt;br /&gt;Matt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-735828436482577414?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/735828436482577414/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=735828436482577414' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/735828436482577414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/735828436482577414'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2009/07/version-11-final-of-linq-to-sql-entity.html' title='Version 1.1 Final of LINQ to SQL Entity Base Released'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-7863067326009066106</id><published>2009-07-04T08:10:00.006+10:00</published><updated>2009-07-04T08:27:31.425+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft CRM'/><category scheme='http://www.blogger.com/atom/ns#' term='Javscript'/><title type='text'>Javascript showModalDialog() - Not impressed</title><content type='html'>Recently I was working on an ASP.Net page to put in an IFRAME for Microsoft CRM.  I had a requirement to choose a CRM systemuser from a list, and so naturally I went looking for a way to do this.&lt;br /&gt;&lt;br /&gt;I stumbled across showModalDialog() and thought it was the way to go as it offered a Modal Dialog window which I could put to any URL and also could return any result I wanted back to the calling window really simply.&lt;br /&gt;&lt;br /&gt;So, everything seemed to work great, but as it turns out, it IE 8 seems to cache the Dialog window so everytime that you start it up it would show the very first window that you had that ever used it (not just for that session, but the very first time you used the window with that URL).  This was really odd, I tried several methods for stopping the caching but none of them seemed to work - even changing the URL to be unique every time didn't even stop it!&lt;br /&gt;&lt;br /&gt;At the end of the day I gave up after finding out so many other people were having problems with it, and that it's functionality and become "flakey-er" as new revisions of IE were released (I also discovered that it's an IE only feature).&lt;br /&gt;&lt;br /&gt;I ended up just re-arranging my base page (the one that i put in the IFRAME) to include the some functionality.&lt;br /&gt;&lt;br /&gt;From now on I'll be avoiding the showModalDialog() - as I wouldn't be surprised if it doesn't work at all in the next version of IE.  And although I ended up not using any type of Modal in this instance, I did find examples of how it's possible to do it with standard (non IE specific) code.&lt;br /&gt;&lt;br /&gt;Lesson Learnt!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-7863067326009066106?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/7863067326009066106/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=7863067326009066106' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/7863067326009066106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/7863067326009066106'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2009/07/javascript-showmodaldialog-not.html' title='Javascript showModalDialog() - Not impressed'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-8599630703469242505</id><published>2009-04-25T09:35:00.006+10:00</published><updated>2009-04-25T09:48:52.013+10:00</updated><title type='text'>Project your class attributes into a data table.</title><content type='html'>A friend of mine has written a small tool which allows you to project attributes of your classes into a data table, which you can then use for data binding or reporting.  The main reason for doing such a thing is to help out with sorting without having to re-bind the data between sorts.&lt;br /&gt;&lt;br /&gt;If your in need of such a thing, please follow this link:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/modelshredder/"&gt;http://code.google.com/p/modelshredder/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-8599630703469242505?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/8599630703469242505/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=8599630703469242505' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/8599630703469242505'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/8599630703469242505'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2009/04/project-your-into-data-table.html' title='Project your class attributes into a data table.'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-5411246244552567114</id><published>2009-03-24T12:15:00.001+11:00</published><updated>2009-03-24T12:15:10.777+11:00</updated><title type='text'>CRM 4.0 Many to Many Importer Tool</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;Hi everyone,&lt;br /&gt;&lt;/p&gt;&lt;p&gt;I was surprised there didn't seem to be any easy way to import N-N database relationship data into the database, and as you can't do it yourself via T-SQL inserts I have written a tool to import many to many relationship data (N – N) into the database – which may be helpful for someone out there.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The project has been published on &lt;a href='http://crmmanytomanyimport.codeplex.com/'&gt;Codeplex Here&lt;/a&gt; along with the instructions on how to use it.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Cheers&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Matt.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-5411246244552567114?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/5411246244552567114/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=5411246244552567114' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/5411246244552567114'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/5411246244552567114'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2009/03/crm-40-many-to-many-importer-tool.html' title='CRM 4.0 Many to Many Importer Tool'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-4683629713794749136</id><published>2009-02-23T17:37:00.005+11:00</published><updated>2009-02-23T18:10:27.218+11:00</updated><title type='text'>CRM 4.0 Picklist Generator Tool</title><content type='html'>Hi everyone,&lt;br /&gt;&lt;br /&gt;To generate the picklist options in the application I work on, i'm always using the &lt;a href="http://www.beatnik.at/picklist_for_mscrm.php"&gt;CRM 4.0 Picklist Item generator &lt;/a&gt;created by &lt;a href="http://marioraunig.blogspot.com/"&gt;http://marioraunig.blogspot.com/&lt;/a&gt;, which I think is a great tool - quick and easy!&lt;br /&gt;&lt;br /&gt;Often however I find that I need a few more features and so i've written my own utility for generating these codes, which over time I plan on adding more features too.&lt;br /&gt;&lt;br /&gt;Find it here:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.codeplex.com/CRMPicklistGenerator"&gt;http://www.codeplex.com/CRMPicklistGenerator&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_nrt4ht8y-jk/SaJLvUVtgnI/AAAAAAAAABI/a8W75nV0S-c/s1600-h/Untitled.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 212px;" src="http://3.bp.blogspot.com/_nrt4ht8y-jk/SaJLvUVtgnI/AAAAAAAAABI/a8W75nV0S-c/s320/Untitled.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5305886587281572466" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For the moment, I've added the following features which I've found useful....&lt;br /&gt;&lt;br /&gt;1. You can specify which number to use as the picklist value.&lt;br /&gt;2. Options are specified as&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;[value], [description]&lt;/strong&gt;&lt;br /&gt;OR&lt;br /&gt;&lt;strong&gt;[value],"[description]"&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;where [value] is the underlying value (int) and [description] is the pick list option description that's shown to the user.&lt;br /&gt;&lt;br /&gt;3. You can sort by the description (deals with comma's in description as well).&lt;br /&gt;4. You can specify which language code you want the list to use.&lt;br /&gt;5. Allows comma's in descriptions and removes quotes&lt;br /&gt;&lt;br /&gt;In order to use it,&lt;br /&gt;&lt;br /&gt;1. Generate the option list&lt;br /&gt;2. Open up your customization.xml file in Notepad or Visual Studio&lt;br /&gt;3. Find the appropriate section of the xml file&lt;br /&gt;4. Paste the generated option list into the xml file&lt;br /&gt;5. Re-import the customization.xml file.&lt;br /&gt;&lt;br /&gt;Anyway, hope it's handy for someone out there...&lt;br /&gt;&lt;br /&gt;Cheers&lt;br /&gt;&lt;br /&gt;Matt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-4683629713794749136?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.codeplex.com/CRMPicklistGenerator' title='CRM 4.0 Picklist Generator Tool'/><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/4683629713794749136/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=4683629713794749136' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/4683629713794749136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/4683629713794749136'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2009/02/crm-40-picklist-generator-tool.html' title='CRM 4.0 Picklist Generator Tool'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_nrt4ht8y-jk/SaJLvUVtgnI/AAAAAAAAABI/a8W75nV0S-c/s72-c/Untitled.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-7282199460299854642</id><published>2009-01-19T22:11:00.002+11:00</published><updated>2009-01-19T22:23:21.277+11:00</updated><title type='text'>Update Rollup 2 for Microsoft Dynamics CRM 4.0</title><content type='html'>It looks like Microsoft have release the second rollup package for Microsoft CRM 4.0 in only a matter of months! &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I only hope that CRM 5.0 comes sooner than expected too :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Find the information &lt;a href="http://support.microsoft.com/kb/959419"&gt;here&lt;/a&gt; and the download for the rollup package &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=aa671769-61e9-45c4-919f-c88199aa4241&amp;amp;displaylang=en&amp;amp;tm"&gt;here&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-7282199460299854642?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/7282199460299854642/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=7282199460299854642' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/7282199460299854642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/7282199460299854642'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2009/01/update-rollup-2-for-microsoft-dynamics.html' title='Update Rollup 2 for Microsoft Dynamics CRM 4.0'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-4840977743671900064</id><published>2008-12-16T10:40:00.004+11:00</published><updated>2008-12-16T11:53:39.531+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft CRM'/><title type='text'>Host [Name] failed while starting monitoring asynchronous operations queue.</title><content type='html'>I've started working on some Microsoft Dynamics CRM development lately, and came accross this issue with on of our servers when the CRM Asyncronous Service stopped:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;Host [Name] failed while starting monitoring asynchronous operations queue.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you have the ApplicationServer and PlatformServer installed on the same machine, you may receive this error (in the event log) when you try and start the service&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;Host SGCORPCRM1: failed while starting monitoring asynchronous operations queue. Exception: System.InvalidOperationException: The requested Performance Counter is not a custom counter, it has to be initialized as ReadOnly.&lt;br /&gt;at System.Diagnostics.PerformanceCounter.Initialize()&lt;br /&gt;at System.Diagnostics.PerformanceCounter..ctor(String categoryName, String counterName, String instanceName, Boolean readOnly)&lt;br /&gt;at Microsoft.Crm.Asynchronous.PerformanceCounters..ctor(String instanceName)&lt;br /&gt;at Microsoft.Crm.Asynchronous.AsyncService.OnStart(String[] args)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I'm not sure how this happenned, I had a look for answers and found a &lt;a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;958377&amp;amp;sd=rss&amp;amp;spid=12976"&gt;Microsft KB &lt;/a&gt;on the problem - which was similar, but this did not seem to be applicable.&lt;br /&gt;&lt;br /&gt;After some more searching, I finally found a &lt;a href="http://www.eggheadcafe.com/software/aspnet/32331632/failed-while-starting-mon.aspx"&gt;post in the eggheadcafe forums &lt;/a&gt;, which came up with the goods (thanks Deepak!). Of course, before applying this fix, I checked a working server first, and found that the RoleNames and Roles registry entries were infact incorrect.&lt;br /&gt;&lt;br /&gt;Below I've repeated the steps, hopefully making it easier to find for other with the same issue.&lt;br /&gt;Open the registry and go to the path HKLM\SOFTWARE\Microsoft\MSCRM&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Check the 'RoleNames' value and the 'roles' value - they should be set to the following values "ApplicationServer,PlatformServer" and "2392107" ( do not include quotes) &lt;/li&gt;&lt;li&gt;If the values do not match these, correct them to be the same &lt;/li&gt;&lt;li&gt;Repair the CRM Installation &lt;/li&gt;&lt;li&gt;Restart IIS The service should start successfully now.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-4840977743671900064?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/4840977743671900064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=4840977743671900064' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/4840977743671900064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/4840977743671900064'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2008/12/host-name-failed-while-starting.html' title='Host [Name] failed while starting monitoring asynchronous operations queue.'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-3348090080723268086</id><published>2008-12-05T06:28:00.002+11:00</published><updated>2008-12-05T06:50:11.003+11:00</updated><title type='text'>LINQ to SQL Entity Base Version 1.0 Final</title><content type='html'>Hi everyone,&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now that all the bugs seem to be ironed out in the the LINQ to SQL Entity Base class, it's time to release it to the world as a final version.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you have been using RC3, there is no need to update the source code from the Final release source code as it has not changed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As with the RC3 release, I will stress again that you need Visual Studio 2008 SP1 and .NET 3.5 SP1 to run this final release verison as it uses one of the attributes for serialization not found in the original .NET 3.5 version.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Find the final version here:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.codeplex.com/LINQ2SQLEB/Release/ProjectReleases.aspx"&gt;http://www.codeplex.com/LINQ2SQLEB/Release/ProjectReleases.aspx&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyway, have fun!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Cheers&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Matt.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-3348090080723268086?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/3348090080723268086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=3348090080723268086' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/3348090080723268086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/3348090080723268086'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2008/12/linq-to-sql-entity-base-version-10.html' title='LINQ to SQL Entity Base Version 1.0 Final'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-6149389209942176211</id><published>2008-10-22T12:01:00.002+11:00</published><updated>2008-10-22T12:08:28.004+11:00</updated><title type='text'>Linq to SQL Entity Base Release Candidate 3</title><content type='html'>Hi everyone,&lt;br /&gt;&lt;br /&gt;I've released a new version of the Linq 2 SQL Entity Base class which can be found here, along with details of the changes:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.codeplex.com/LINQ2SQLEB/Release/ProjectReleases.aspx?ReleaseId=18662"&gt;http://www.codeplex.com/LINQ2SQLEB/Release/ProjectReleases.aspx?ReleaseId=18662&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I'm hoping this is the final release candidate that will become version 1.0 gold.&lt;br /&gt;&lt;br /&gt;Cheers&lt;br /&gt;&lt;br /&gt;Matt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-6149389209942176211?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.codeplex.com/LINQ2SQLEB/Release/ProjectReleases.aspx?ReleaseId=18662' title='Linq to SQL Entity Base Release Candidate 3'/><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/6149389209942176211/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=6149389209942176211' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/6149389209942176211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/6149389209942176211'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2008/10/linq-to-sql-entity-base-release.html' title='Linq to SQL Entity Base Release Candidate 3'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-4892125493833665798</id><published>2008-10-10T11:25:00.008+11:00</published><updated>2008-10-10T12:20:26.825+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Team Foundation Server'/><title type='text'>TFS - Fixing Work Item Updates made in Excel</title><content type='html'>One of the cool things about TFS is it's integration with Excel.  The integration allows you to link work item data and publish it back to TFS, which is really handy for BA's, Team Leaders and Project Managers.&lt;br /&gt;&lt;br /&gt;Unfortunately, with this feature comes the ability to make a huge mistake as well if you are not careful.&lt;br /&gt;&lt;br /&gt;Recently, I had to find a way to revert 400 hundred work items which were unintentionally updated by one of the business team.  They were using excel, copying and pasting from one TFS linked document into another and accidentally answered "yes" to the publish on the target excel document which resulted in every work items title and description being overridden.&lt;br /&gt;&lt;br /&gt;Unfortunately, there was not quick and easy way to revert this so I had to figure out some way of doing it.&lt;br /&gt;&lt;br /&gt;What I came up with was rather than trying to rollback the changes by fiddling with the TFS database (which is also a very risky thing to do) I thought that I would just override the mistaken records with the previous data (ironically with Excel - which is the same thing that made the mess!) and leave the invalid data in the workitem, so it would dissappear in the history.&lt;br /&gt;&lt;br /&gt;Here's what I did:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Queried the "workitemsare" table and the "workitemswere" table to find those records which were accidentally updated (looking at the change date field and the changed by field to find the right time of the incidient and user who publish the records).&lt;/li&gt;&lt;li&gt;Found the previous version of the records by looking in the "workitemswere" table by comparing the records found in 1. above to the "workitemswere" table and finding the most recent update that occurent before the incident.&lt;/li&gt;&lt;li&gt;From the results, build CSV file that could be opened in excel and be pasted over the top of a TFS linked document containing those records which were affected by the incident.  It's important that both the excel documents (both the extract and the linked document) were in the same work item order and had the same columns that needed to be updated.&lt;/li&gt;&lt;li&gt;Paste the correct values over the top of the bad records in the linked excel spreadsheet.&lt;/li&gt;&lt;li&gt;Publish the correct values back to TFS from excel, resolving any issues where the new "correct" values broke any TFS workitem status state rules.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;If you ever need to do this, here's a sample of the scripts which should get you started:&lt;/p&gt;&lt;p&gt;-----&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#006600;"&gt;-- Create a tempory table to put the data in&lt;/span&gt;&lt;br /&gt;SELECT 1 AS Id,&lt;br /&gt;fld10010 AS Priority,&lt;br /&gt;State,&lt;br /&gt;[Fld10094] ExternalSystemId,&lt;br /&gt;[Assigned To],&lt;br /&gt;Title,&lt;br /&gt;fld10005 As [Resolved Date],&lt;br /&gt;[Changed Date]&lt;br /&gt;INTO #workingtable&lt;br /&gt;FROM workitemsare&lt;br /&gt;WHERE id = null&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#006600;"&gt;-- Grab the data that we are after and throw them into a temp table,&lt;br /&gt;-- filtering by user and approximate time.&lt;br /&gt;&lt;/span&gt;INSERT INTO #workingtable&lt;br /&gt;(&lt;br /&gt;id,&lt;br /&gt;Priority,&lt;br /&gt;State,&lt;br /&gt;ExternalSystemId,&lt;br /&gt;[Assigned To],&lt;br /&gt;Title,&lt;br /&gt;[Resolved Date],&lt;br /&gt;[Changed Date]&lt;br /&gt;)&lt;br /&gt;SELECT id,&lt;br /&gt;fld10010 AS Priority,&lt;br /&gt;State,&lt;br /&gt;[Fld10094] ExternalSystemId,&lt;br /&gt;[Assigned To],&lt;br /&gt;Title,&lt;br /&gt;fld10005 As [Resolved Date],&lt;br /&gt;[Changed Date]&lt;br /&gt;FROM workitemsare&lt;br /&gt;WHERE [changed by] = '[user name]'&lt;br /&gt;AND [changed date] BETWEEN '2008-08-26 08:41:00'&lt;br /&gt;AND '2008-08-26 08:42:00'&lt;br /&gt;UNION&lt;br /&gt;SELECT id,&lt;br /&gt;fld10010 AS Priority,&lt;br /&gt;State,&lt;br /&gt;[Fld10094] ExternalSystemId,&lt;br /&gt;[Assigned To],&lt;br /&gt;Title,&lt;br /&gt;fld10005 As [Resolved Date],&lt;br /&gt;[Changed Date]&lt;br /&gt;FROM workitemswere&lt;br /&gt;WHERE [changed by] = '[user name]'&lt;br /&gt;AND [changed date] BETWEEN '2008-08-26 08:41:00'&lt;br /&gt;AND '2008-08-26 08:42:00'&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:verdana;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#006600;"&gt;-- select the correct records (finding the most recent change before the incident),&lt;br /&gt;-- making sure that the column order and record order match that of excel spread sheet&lt;br /&gt;-- you will use to paste over the top&lt;br /&gt;-- (export this to CSV)&lt;/span&gt;&lt;br /&gt;SELECT WIW.id,&lt;br /&gt;ISNULL(CAST(WIW.fld10010 AS VARCHAR(10)), '') AS Priority,&lt;br /&gt;WIW.State,&lt;br /&gt;ISNULL(WIW.[Fld10094], '') AS ExternalSystemId,&lt;br /&gt;WIW.[Assigned To],&lt;br /&gt;WIW.Title,&lt;br /&gt;WIW.fld10005 As [Resolved Date],&lt;br /&gt;WIW.[Changed Date]&lt;br /&gt;FROM #workingtable MWT&lt;br /&gt;INNER JOIN [WorkItemsWere] WIW ON MWT.Id = WIW.Id&lt;br /&gt;WHERE WIW.[Changed Date] = ( SELECT MAX([Changed Date])&lt;br /&gt;FROM [WorkItemsWere] AS WIW2&lt;br /&gt;WHERE WIW.Id = WIW2.Id&lt;br /&gt;AND WIW2.[Changed Date] &lt; '2008-08-26 08:41:00'&lt;br /&gt;)&lt;br /&gt;GROUP BY WIW.id,&lt;br /&gt;WIW.fld10010,&lt;br /&gt;WIW.State,&lt;br /&gt;WIW.[Fld10094],&lt;br /&gt;WIW.[Assigned To],&lt;br /&gt;WIW.Title,&lt;br /&gt;WIW.fld10005,&lt;br /&gt;WIW.[Changed Date]&lt;br /&gt;ORDER BY WIW.Id&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;----&lt;/p&gt;&lt;p&gt;Notes:&lt;/p&gt;&lt;p&gt;- Some of the fields have column values that aren't well named (auto genereated by TFS), to find where they are, look in the Fields table for the correct field/column mapping.&lt;/p&gt;&lt;p&gt;- WorkItemsWere, WorkItemsAre, Field tables can be found in the "TfsWorkItemTracking" database.&lt;/p&gt;&lt;p&gt;- WorkItemsWere table contains the previous states of each work item&lt;/p&gt;&lt;p&gt;- WorkItemsAre table contains the latest values for each work item&lt;/p&gt;&lt;p&gt;- DO NOT modify the TFS database directly!!!!&lt;/p&gt;&lt;br /&gt;Cheers&lt;br /&gt;&lt;br /&gt;Matt&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-4892125493833665798?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/4892125493833665798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=4892125493833665798' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/4892125493833665798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/4892125493833665798'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2008/10/tfs-fixing-work-item-updates-made-in.html' title='TFS - Fixing Work Item Updates made in Excel'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-6545753355416806117</id><published>2008-08-08T11:27:00.004+10:00</published><updated>2008-10-10T11:18:15.082+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Service'/><title type='text'>Run Sun Java Application Server 9.1 on Windows Server 2003 as Service</title><content type='html'>I don't usually dabble in the Java world too much, but had to recently because a client required us to use a Java Solution and we needed to integrate with as part of our Windows Workflow Foundation. This solution Runs under Sun Java Application Server (SJAS).&lt;br /&gt;&lt;br /&gt;Installation of the JAR file in SJAS worked fine as a Service and everything seemed to be going great. Right up until I logged off the server - this is where the service stop responding to calls but the service itself still beleived everything was working fine. This was weird because if you choose to install as a service, you don't expect it stop when you logout (i.e.the whole reason for having the "windows service" concept).&lt;br /&gt;&lt;br /&gt;There seemed to be a lot of people out there looking for a solution to this issue, but no one seemed to have the answer (at least not for Windows 2003/SJAS 9.1 combination). Not even the vendor of the solution we were integrating with had a solution to this problem.&lt;br /&gt;&lt;br /&gt;It turns out that the information is actually in the documentation for SJAS after all - which tripped me up because my searched kept taking me to the old 8.x version SJAS which doesn't include the extra special setting for Windows 2003, and following the 8.x version doesn't work.&lt;br /&gt;&lt;br /&gt;Anyway, here's the information and a link to the Sun documenation - it's a bit of fiddling, but it works fine once you make these changes.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://docs.sun.com/app/docs/doc/819-3671/ablwz?l=en&amp;amp;a=view&amp;amp;q=Restarting+Automatically"&gt;http://docs.sun.com/app/docs/doc/819-3671/ablwz?l=en&amp;amp;a=view&amp;amp;q=Restarting+Automatically&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;strong&gt;Preventing the Service From Shutting Down When a User Logs Out&lt;/strong&gt;&lt;br /&gt;By default, the Java VM catches signals from Windows that indicate that the operating system is shutting down, or that a user is logging out, and shuts itself down cleanly. This behavior causes the Application Server service to shut down when a user logs out of Windows. To prevent the service from shutting down when a user logs out, set the -Xrs Java VM option.&lt;br /&gt;&lt;br /&gt;To set the -Xrs Java VM option, add the following line to the section of the as-install\domains\domain-name\config\domain.xml file that defines Java VM options:&lt;br /&gt;&lt;br /&gt;&lt;jvm-options&gt;-Xrs&lt;/JVM-OPTIONS&gt;If the Application Server service is running, stop and restart the service for your changes to become effective.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;And the all imporant bit...&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;&lt;br /&gt;Note –&lt;br /&gt;In some Windows 2003 Server installations, adding the -Xrs option to the domain.xml file fails to prevent the service from shutting down. In this situation, add the option to the as-install\lib\processLauncher.xml file as follows:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;lt;process name="as-service-name"&amp;gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;sysproperty key="-Xrs"/&amp;gt;&lt;br /&gt;...&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-6545753355416806117?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/6545753355416806117/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=6545753355416806117' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/6545753355416806117'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/6545753355416806117'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2008/08/run-sun-java-application-server-91-on.html' title='Run Sun Java Application Server 9.1 on Windows Server 2003 as Service'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-4345426354369948853</id><published>2008-07-03T12:17:00.011+10:00</published><updated>2008-10-10T11:18:39.626+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Service'/><title type='text'>Debugging Windows Services in Visual Studio 2002/3/5/8</title><content type='html'>Just a quick tip on something I've been doing for years.&lt;br /&gt;&lt;br /&gt;If you want to debug your Windows Service without having to install it as a service on your development machine first, you can use the "DEBUG" compiler constant to direct the compiler constant to run your service just as an executable instead of spinning up a service.&lt;br /&gt;&lt;br /&gt;To do this in C# (basically the same steps in VB as well), open the Program.cs file and wrap the main method contents in a #if(!DEBUG), #else and #endif. Between the #else and #endif, simply put in the code that invokes the application logic.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You can see my example below, I've simply created a class called "ProcessFiles" and added static start and stop methods that starts/stops the processing as it normally would in a service. In the Program.cs file, i've then simply called the start method, put in a message box to stop the process falling through and stopping until developer debugging is read to quit, and a call to the stop method to cease processing.&lt;br /&gt;&lt;br /&gt;From there it was just a simple matter of hooking up the OnStart and OnStop events of the actual service class of these methods as well.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; ExampleService&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Program&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="rem"&gt;/// The main entry point for the application.&lt;/span&gt;&lt;br /&gt;        &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main()&lt;br /&gt;        {&lt;br /&gt;#&lt;span class="kwrd"&gt;if&lt;/span&gt;(!DEBUG)&lt;br /&gt;&lt;br /&gt;           &lt;br /&gt;            ServiceBase[] ServicesToRun;&lt;br /&gt;            ServicesToRun = &lt;span class="kwrd"&gt;new&lt;/span&gt; ServiceBase[]&lt;br /&gt;            {&lt;br /&gt;                &lt;span class="kwrd"&gt;new&lt;/span&gt; Service()&lt;br /&gt;            };&lt;br /&gt;            ServiceBase.Run(ServicesToRun);&lt;br /&gt;&lt;span class="preproc"&gt;#else&lt;/span&gt;&lt;br /&gt;            ProcessFiles.Start();&lt;br /&gt;            MessageBox.Show(&lt;span class="str"&gt;"Debugging has started. To stop debugging click ok"&lt;/span&gt;);&lt;br /&gt;            ProcessFiles.Stop();&lt;br /&gt;           &lt;br /&gt;&lt;span class="preproc"&gt;#endif&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The "DEBUG" compliler constant is linked to the Build Properties Page on a C# project. By defualt this is ON for the "DEBUG" build configuration, but OFF for releases. You'll notice if you are looking at the code, that when your build configuration is set to "DEBUG:, the generated service code will be greyed out and the custom code comes to life. Switching to "RELEASE" config reverses this situation. Nice touch I think ;)&lt;br /&gt;&lt;br /&gt;Now I can use the "RELEASE" config to build an exe so my solution can be deployed as a service for testing/production OR simply run it in the Visual Studio debugger under the "DEBUG" config without having to install it as a service on my dev machine.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Cheers&lt;br /&gt;&lt;br /&gt;Matt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-4345426354369948853?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/4345426354369948853/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=4345426354369948853' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/4345426354369948853'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/4345426354369948853'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2008/07/debugging-windows-services-in-visual.html' title='Debugging Windows Services in Visual Studio 2002/3/5/8'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-7780075829688321343</id><published>2008-06-25T20:31:00.007+10:00</published><updated>2008-10-10T11:18:51.052+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hyper-V'/><title type='text'>Hyper-V - Great for Developers</title><content type='html'>I've been using Microsofts Hyper-V software for the last month and I gotta say I'm impressed.&lt;br /&gt;&lt;br /&gt;At work, we've setup box with 1 Terrabyte of Hard Drive Space (Raid 10), 16GB of RAM and two Quad Core Xeons running Windows Server 2008 x64 and Hypervisor. This is being used for our Test and User Acceptance platform - allow us to create our environments very rapidly (with some help from Sys Prep) and performance is amazing considering we are running 10 VPC's, some even running Biztalk + SQL server instances inside the virtuals as well. I have not yet seen even a hint of any drop in performance and still plenty of room for expansion with this hardware.&lt;br /&gt;&lt;br /&gt;The difference between Hyper-V and other Microsoft Virtual technolgies is that the Windows 2008 OS actually allows Hyper-V to sit a hell of a lot closer to the metal (i.e. less layers between the Virtual and the Physical hardware) while still doing a great job of distributing the load of the VPC's accross the machine. It totally rocks compared to Virtual PC Server - it isn't even close to Hyper-V on performance.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It has definately development lives much easier, being able to spin up a new Syspreped OS, drop it on, hook it up to the network and then install whatever we need. The other thing we've been able to do is to port physical machines to virtual (this comes as an easy step by step wizard) - although I have come across some issues and couldn't get some machines to move accross so easily, but this has let us move our current enviroments on seperate physical machines quickly into the virtual fold. I was further impressed in most cases that you can port a machine from physical to virtual while the physical machine your porting is still online.&lt;br /&gt;&lt;br /&gt;Just some things to note if you are interested when using the release candidate...&lt;br /&gt;&lt;br /&gt;1. It only runs on Windows Server x64 OS, no other OS is supported.&lt;br /&gt;&lt;br /&gt;2. It's currently only at a Release Candidate.&lt;br /&gt;&lt;br /&gt;3. Although Windows 2008 Server x64 contains the Integration Services components that are required for it be a guest, these are only compatible with Beta 2 of Hyper-V - When using the release candidate you will need to install a patch in the guest OS to allow these drivers to install correctly (See http://support.microsoft.com/kb/949219).&lt;br /&gt;&lt;br /&gt;4. When migrating from a previous Virtual PC VHD to Hyper-V, it may not detect the VMBUS and other things correctly, leaving you without some of the comforts of the Integration Services compents. In order to fix this, use Start--&gt;Run MSCONFIG--&gt;Boot Tab--&gt;Advanced Options and Click Detect HAL and reboot.&lt;br /&gt;&lt;br /&gt;5. Also when migrating a previous Virtual PC VHD to Hyper-V, if you can't initally get any network access in the Hyper-V admin tool, set the Virtual PC up so it's using a Legacy network driver - this should fix it.&lt;br /&gt;&lt;br /&gt;6. If you are stuck wondering why you can't log into the Hyper-V Adminstration tool, you'll need to get the user that original installed Hyper-V on the machine to log into it first and add you as an Administrator before you can use it yourself.&lt;br /&gt;&lt;br /&gt;Anyway, check out this for more info&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/windowsserver2008/en/us/virtualization-consolidation.aspx"&gt;http://www.microsoft.com/windowsserver2008/en/us/virtualization-consolidation.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Cheers&lt;br /&gt;&lt;br /&gt;Matt&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-7780075829688321343?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/7780075829688321343/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=7780075829688321343' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/7780075829688321343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/7780075829688321343'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2008/06/hyper-v-great-for-developers.html' title='Hyper-V - Great for Developers'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-4848690215984994713</id><published>2008-05-20T20:47:00.007+10:00</published><updated>2008-10-10T11:19:05.482+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq to SQL'/><title type='text'>LINQ2SQL "IS" the DAL</title><content type='html'>When I first started off with LINQ to SQL, my first intincts were to wrap it in a data acces layer just like we had on many previous projects with ADO.NET, but after using it for a short while I realised one important thing - LINQ to SQL is the Data Access Layer.&lt;br /&gt;&lt;br /&gt;The generally accepted method of writing applications in .NET was to have 3 tiers - presentation, business and data. Basically, you had Winforms or ASP.NET in your presentation tier, .NET in the business tier and ADO.NET/SQL Server in your data tier.&lt;br /&gt;&lt;br /&gt;Usually in the data tier, stored procedures would be created for CRUD operations and other business logic. ADO.NET code would them written to wrap these stored procedures that service the business tier.&lt;br /&gt;&lt;br /&gt;This often ended up being quite a lot of T-SQL and .NET code, and because of this it could take quite some time to get just a single vertical slice of functionality running. It would also mean a lot of code to maintain after the product was shipped and bugs/enhancements were made.&lt;br /&gt;&lt;br /&gt;With LINQ to SQL, a lot is simplified (although there's still plenty of room for improvement). There's no need to write tedious CRUD stored procedures which also means that there's no need to write the code to wrap the stored procedures.&lt;br /&gt;&lt;br /&gt;In my opinion, if you go down the route of putting a layer around the LINQ to SQL (the DAL) you are making a mistake. You are adding extra code where it's not needed and reducing productivity and adding to maintenance later on.&lt;br /&gt;&lt;br /&gt;The way I see it, there's no point - there is nothing to gain by wrapping LINQ to SQL up in layers, instead embrace it's elegance by exposing it directly to the business layer and reduce the amount of code you write significantly. Mix it with your business logic - allow it to save you the time which is much better spent in other area's rather than the plumbing.&lt;br /&gt;&lt;br /&gt;Either use the LINQ to SQL entities as your Data Transfer objects or use them as your business entities - either way your still saving on code.&lt;br /&gt;&lt;br /&gt;Of course LINQ to SQL is not perfect, but it's definately a step in the right direction.&lt;br /&gt;&lt;br /&gt;In Summary, this:&lt;br /&gt;&lt;br /&gt;Presentation -&gt; Business -&gt; DAL --&gt; ADO.NET --&gt; TSQL --&gt; DATA&lt;br /&gt;&lt;br /&gt;Becomes this:&lt;br /&gt;&lt;br /&gt;Presentation -&gt; Business -&gt; Linq2SQL --&gt; DATA&lt;br /&gt;&lt;br /&gt;Cheers&lt;br /&gt;&lt;br /&gt;Matt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-4848690215984994713?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/4848690215984994713/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=4848690215984994713' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/4848690215984994713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/4848690215984994713'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2008/05/linq-is-dal.html' title='LINQ2SQL &quot;IS&quot; the DAL'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-6434110001349568593</id><published>2008-05-09T21:35:00.007+10:00</published><updated>2008-10-10T11:19:41.214+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linq to SQL Entity Base'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq to SQL'/><title type='text'>Version 1.0 Release Candidate 1 of LINQ to SQL Entity Base released!!!</title><content type='html'>Hi people,&lt;br /&gt;&lt;br /&gt;I've finally made a release candidate for the LINQ to SQL Entity base which can be found &lt;a href="https://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=LINQ2SQLEB&amp;amp;ReleaseId=13243"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A number of things have been done recently to it, namely:&lt;br /&gt;- Added two static helper methods for serialization/de-serialization of entities.&lt;br /&gt;- Now automatically returns KnownTypes if Entity Base class is in the same assembly as your Entity classes.&lt;br /&gt;- You can now set the initial state of the root entity (e.g. New or Deleted)&lt;br /&gt;- Demo is now in the form of a Client/Server architecture, with WCF used for communication.&lt;br /&gt;- Added "LINQEntityState" property which returns an enum indicating the state of the entity.&lt;br /&gt;&lt;br /&gt;Oh, and i've re-written the home page to include a list of "How To's" covering a lot of the questions i've been asked. Find it &lt;a href="http://www.codeplex.com/LINQ2SQLEB"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;br /&gt;Cheers&lt;br /&gt;&lt;br /&gt;Matt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-6434110001349568593?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/6434110001349568593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=6434110001349568593' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/6434110001349568593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/6434110001349568593'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2008/05/release-candidate-1-release.html' title='Version 1.0 Release Candidate 1 of LINQ to SQL Entity Base released!!!'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-4507338033267215935</id><published>2008-04-30T08:13:00.005+10:00</published><updated>2008-10-10T11:20:11.608+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linq to SQL Entity Base'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq to SQL'/><title type='text'>Another LINQ to SQL Entity Base Improvement</title><content type='html'>Just a quick note that the latest source code includes a WCF serialization enhancement being that that you no longer have to specifically mention Known Types - this is being done automagically now.&lt;br /&gt;&lt;br /&gt;A new release will follow in the next day or so.&lt;br /&gt;&lt;br /&gt;Cheers&lt;br /&gt;&lt;br /&gt;Matt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-4507338033267215935?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/4507338033267215935/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=4507338033267215935' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/4507338033267215935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/4507338033267215935'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2008/04/linq-to-sql-entity-base-improvement-2.html' title='Another LINQ to SQL Entity Base Improvement'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-5534702655177331686</id><published>2008-04-23T20:01:00.018+10:00</published><updated>2008-10-10T11:20:43.186+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linq to SQL Entity Base'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq to SQL'/><title type='text'>LINQ to SQL Entity Base Improvement</title><content type='html'>Well,&lt;br /&gt;&lt;br /&gt;I've been at it again... This time i've added some requested features that will come in handy for some of you.&lt;br /&gt;&lt;br /&gt;These changes are:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;1. There is no longer need to have a timestamp field&lt;/strong&gt;&lt;br /&gt;In earlier versions you had to have a timestamp column primarily because it was the easiest way for me to figure out if an object was new or not. If the column was NULL this meant that I could tell that the object was brand new, if it wasnt't null it meant that the object had been retrieved from the database.&lt;br /&gt;&lt;br /&gt;This is no longer needed, as now when you invoke "SetAsChangeTrackingRoot()" it will go through the Entity Tree and mark all entities as IsNew = false. Then, when an entity added somewhere on the entity tree, i detect that it's a new entity (when the FK changes from NULL to the parents ID) and mark IsNew = true on the object.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;2. Option to keep original entity values.&lt;/strong&gt;&lt;br /&gt;When a timestamp (version) column is available on a table, by default it is used by LINQ to SQL to peform concurrency checks when submitting updates and deletes to the database.&lt;br /&gt;&lt;br /&gt;Because I have removed the requirement to have a timestamp (version) column on a table, I had to allow for the other method of concurrency checking which is to use the UpdateCheck property that is available on every column in the dbml model.&lt;br /&gt;&lt;br /&gt;When the UpdateCheck property is set to "Always" on a column, LINQ to SQL compares the original value of this column against current value in the database before it updates or deletes the record. This is intended to make sure another process has not come in and changed the data since you last retrieved it.&lt;br /&gt;&lt;br /&gt;Of course, it's up to the developer to choose the best column(s) for concurrency checks (usually a date/timestamp or update counter of some sort). By default if there is no timestamp column on the table, LINQ to SQL will set all columns = "Always" so that every column is checked in the record for change before an update is done. This is a very safe way to go, but is a little more expensive that just checking a single column.&lt;br /&gt;&lt;br /&gt;In order for the UpdateCheck property to work however, the original value has to be available and when working in a disconnected model this is not the case. The first thought was to use the MemberwiseClone() method, but I needed to shallow copy the original version of the record somehow without including it's references (which MemberwiseClone does). To get around it, I created the following method:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;        &lt;span class="rem"&gt;/// Make a shallow copy of column values without copying references of the source entity&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;        &lt;span class="rem"&gt;/// &amp;lt;param name="source"&amp;gt;the source entity that will have it's values copied&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; LINQEntityBase ShallowCopy(LINQEntityBase source)&lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;        {&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;            PropertyInfo[] sourcePropInfos = source.GetType().GetProperties(BindingFlags.Public  BindingFlags.Instance);&lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;            PropertyInfo[] destinationPropInfos = source.GetType().GetProperties(BindingFlags.Public  BindingFlags.Instance);&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;            &lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;// create an object to copy values into&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;            Type entityType = source.GetType();&lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;            LINQEntityBase destination;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;            destination = Activator.CreateInstance(entityType) &lt;span class="kwrd"&gt;as&lt;/span&gt; LINQEntityBase;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt; &lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (PropertyInfo sourcePropInfo &lt;span class="kwrd"&gt;in&lt;/span&gt; sourcePropInfos)&lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;            {&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (Attribute.GetCustomAttribute(sourcePropInfo, &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(ColumnAttribute), &lt;span class="kwrd"&gt;false&lt;/span&gt;) != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;                {&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;                    PropertyInfo destPropInfo = destinationPropInfos.Where(pi =&amp;gt; pi.Name == sourcePropInfo.Name).First();&lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;                    destPropInfo.SetValue(destination, sourcePropInfo.GetValue(source, &lt;span class="kwrd"&gt;null&lt;/span&gt;), &lt;span class="kwrd"&gt;null&lt;/span&gt;);&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;                }&lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;            }&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt; &lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; destination;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The ShallowCopy method creates a new instance of the source entity, copies all the values from the original to the new instance and returns the new instance.&lt;br /&gt;&lt;br /&gt;You can specify that you want to keep original values when calling the "SetAsChangeTrackingRoot()" method.&lt;br /&gt;&lt;br /&gt;Some things to note:&lt;br /&gt;1. LINQ to SQL will throw an exception if you specify that you want updates checks on columns and you have not indicated that you want to keep original values. This is reasonable, because you need the orignal values to do update checks in the first place...&lt;br /&gt;&lt;br /&gt;2. I've updated the demo to include a tick box, clicking this will keep the original values as described above. I've removed the timestamp fields from the dbml model so to try out conurrency using the UpdateCheck property, simply modify the customer table and change one or more of the column's UpdateCheck properties to true.&lt;br /&gt;&lt;br /&gt;3. An advantage of keeping the original information is that LINQ to SQL can detect just the columns that have changed and only generate an UPDATE T-SQL statement which updates those particular fields. This is good for those tables that have a lot of columns, becaues the T-SQL generated is smaller and there's less work for the database to do as it's potentially updating less columns.&lt;br /&gt;&lt;br /&gt;For example,&lt;br /&gt;&lt;br /&gt;// Running without the original values when updateing the freight value on an order&lt;br /&gt;// will create this (note every column is updated)&lt;br /&gt;&lt;br /&gt;UPDATE [dbo].[Orders]&lt;br /&gt;SET [CustomerID] = @p1, [EmployeeID] = @p2, [OrderDate] = @p3, [RequiredDate] = @p4, [ShippedDate] = @p5, [ShipVia] = @p6, [Freight] = @p7, [ShipName] = @p8, [ShipAddress] = @p9, [ShipCity] = @p10, [ShipRegion] = @p11, [ShipPostalCode] = @p12, [ShipCountry] = @p13&lt;br /&gt;WHERE [OrderID] = @p0&lt;br /&gt;&lt;br /&gt;// Running with original values will create this (note it only updates the freight value)&lt;br /&gt;&lt;br /&gt;UPDATE [dbo].[Orders]&lt;br /&gt;SET [Freight] = @p1&lt;br /&gt;WHERE [OrderID] = @p0&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The Source Code&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I'll be publishing the source code later today, when it's ready grab the &lt;a href="http://www.codeplex.com/LINQ2SQLEB/SourceControl/ListDownloadableCommits.aspx"&gt;source code here&lt;/a&gt; - I'll do a realease (Beta 4) once I'm satisified it's stable&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Other notes&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I would still recommend using a timestamp (rowversion) column if possible because it is the absolute best and easiest way to detect changes in a record.&lt;br /&gt;&lt;br /&gt;The reason it is a good choice is that the timestamp (rowversion) column value is changed for every update made on a record.&lt;br /&gt;&lt;br /&gt;Unlike other databases, the SQL Server version of a timestamp is not related to time, instead it's actually an 8 byte binary value that is unique within the entire database (not just unique within the table).&lt;br /&gt;&lt;br /&gt;This is commonly mis-understood especially for people coming from other database systems which use a time based timestamp value. The issue being with time based timestamps is that you can get duplicates.&lt;br /&gt;&lt;br /&gt;See &lt;a href="http://msdn2.microsoft.com/en-us/library/ms182776.aspx"&gt;books online &lt;/a&gt;for more information.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-5534702655177331686?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/5534702655177331686/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=5534702655177331686' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/5534702655177331686'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/5534702655177331686'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2008/04/improvement-no-requirement-for.html' title='LINQ to SQL Entity Base Improvement'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-8569738404064970383</id><published>2008-04-14T22:06:00.005+10:00</published><updated>2008-10-10T11:20:56.789+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linq to SQL Entity Base'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq to SQL'/><title type='text'>New Version of LINQ to SQL Entity Base Class (Beta 3.0)</title><content type='html'>Hello there!&lt;br /&gt;&lt;br /&gt;Due to popular demand (well at least one person wanted it!) the LINQ to SQL Entity base now supports it... (in thoery!). Find V1.0 Beta 3.0 &lt;a href="https://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=LINQ2SQLEB&amp;amp;ReleaseId=12556"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In the example that comes with the LINQ to Entity Base, i've used the data contract serializer (which is what WCF uses to serialize/deserialize objects) to demonstrate this. I've also improved the example so you can scroll through the results by converting it to a simple windows form.&lt;br /&gt;&lt;br /&gt;Don't forget the following when using it in your own projects:&lt;br /&gt;1. You need to set serialization on your data context to uni-directional.&lt;br /&gt;2. You need to use the KnownTypes for you're entities (this is because of the inheritence of entities from the LINQ to SQL Entity base - for more info, see &lt;a href="http://blogs.msdn.com/sowmy/archive/2006/06/06/618877.aspx"&gt;Sowmy Srinivasan's&lt;/a&gt; blog).&lt;br /&gt;&lt;br /&gt;Cheers&lt;br /&gt;&lt;br /&gt;Matt&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-8569738404064970383?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='https://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=LINQ2SQLEB&amp;ReleaseId=12556' title='New Version of LINQ to SQL Entity Base Class (Beta 3.0)'/><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/8569738404064970383/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=8569738404064970383' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/8569738404064970383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/8569738404064970383'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2008/04/new-version-of-linq-to-sql-entity-base.html' title='New Version of LINQ to SQL Entity Base Class (Beta 3.0)'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-4903952670584093244</id><published>2008-03-28T22:11:00.006+11:00</published><updated>2008-03-30T23:10:12.639+11:00</updated><title type='text'>Implementing Disconnected Deletion Change Tracking</title><content type='html'>In one of my previous blog posts, I described some of the difficulties with change tracking entities which have been removed (i.e. deleted).  &lt;br /&gt;&lt;br /&gt;The main problem was that once you remove an entity whilst "disconnected", it's no longer referenced by anything, and so the object disappears and hence the entity is no longer available when re-attaching to a new data context.&lt;br /&gt;&lt;br /&gt;In the short term, I added a property called "IsDeleted" to the entity base which people could use instead of using the remove method (or setting a refrence to a child property to null), but this had it's disadvantages - mainly being that the user would have to set this themselves (i.e. it wouldn't get picked up automatically on remove) and would un-naturally need to keep the object around.&lt;br /&gt;&lt;br /&gt;So the obvious thing to do was to keep a reference (some where?) to the entity when it's deleted (removed), so it can be re-attached and deleted later on.  But where would this entity be kept?  In the parent that deleted it? In the root object perhaps? In an external change tracking object?&lt;br /&gt;&lt;br /&gt;To keep the Entity Base consistant, I decided to keep all the functionality in the Entity Base class, which ruled out having an external object tracking the changes.  &lt;br /&gt;&lt;br /&gt;Then I went through a lot of options regarding where to store the detached objects and came up with the simplest solution possible - I used the existing infrastructure provided by my Entity Base class - the ToEntityTree() method - as this was the option which seemed the least troublesome for the developer to use.&lt;br /&gt;&lt;br /&gt;So, what I have done is implemented "SetAsChangeTrackingRoot()" method which the developer can call before making any changed to the entity objects.  &lt;br /&gt;&lt;br /&gt;The developer would use this method to mark the section of the Entity Tree (the Entity branch) that would be change tracked.&lt;br /&gt;&lt;br /&gt;When this method is invoked on an entity, the following would happen:&lt;br /&gt;&lt;br /&gt;1. A snapshot of the entity branch would be taken from the entity that method was invoked on.&lt;br /&gt;&lt;br /&gt;2. Indicate to each entity in the branch that it is being change tracked.&lt;br /&gt;&lt;br /&gt;The meant a snapshot of the entity branch would be kept locally with the root of the branch, and this also meant the entity that would used for syncronisation with the data context later on.&lt;br /&gt;&lt;br /&gt;From there, it was just a matter of waiting for the property changed event to fire on an entity (exposed by INotifyPropertyChanged), and to look to see if the property being changed was a Foreign Key reference (meaning a child to parent relatinship) and that the value was being set to NULL (i.e. detaching the entity from it's parent).  Once these conditions were met, I set the IsDeleted flag automatically marking the object for delete.&lt;br /&gt;&lt;br /&gt;Next, I modified the ToEntityTree() method to include these "deleted" entities, as these entities would now not be picted up in the traversal of the entity tree, returning a complete list of all entities including the deleted objects.&lt;br /&gt;&lt;br /&gt;The SyncroniseWithDataContext() method then used the information returned from the ToEntityTree() method to figure out what to attach, insert and delete.&lt;br /&gt;&lt;br /&gt;One issue I came accross was the deletion of child entities under the entity that was marked for deletion.  If you simply removed an entity that already had children, the submit changes would fail because &lt;a href="http://msdn2.microsoft.com/en-us/library/bb386996.aspx"&gt;LINQ to SQL doesn't support cascading deletes&lt;/a&gt; unless specified in the Database Schema and so any Foreign key constraints linking to the record being deleted would mean an exception would be thrown by SQL Server.&lt;br /&gt;&lt;br /&gt;I also couldn't rely on the developer to delete the child entities first and then delete the top most entity as they could do it in any order and the order of the deletions is crucial - the child objects must be deleted first.&lt;br /&gt;&lt;br /&gt;Instead, I decided by default to have my own cascade delete functionality so when an object is removed, I automatically remove any child objects starting with the child leaves of the branch first.  This was achieved by call the ToEntityTree() method internally and using the reverse function so that it would be from order from child leave all the way back to the root of the change tracking.&lt;br /&gt;&lt;br /&gt;Even though by default calling the SyncroniseWithDataContext() will perform cascading deletes, I have added an optional parameter so that it can be disabled if need be - which is handy if you didn't expect there to be children of the object you are deleting OR you are handling cascading deletes in the database anyway.&lt;br /&gt;&lt;br /&gt;So thats how I've achieved automatic deletion tracking :).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Some more thoughts&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;After building the LINQ Entity base class in this way, I realised it would be reasonably easy to move all the logic into an external object (not an entity) which was similar to the standard DataContext but performed the tasks in an offline way.&lt;br /&gt;&lt;br /&gt;Some people would feel more comfortable with this perhaps, because of the similarities with the existing data context.&lt;br /&gt;&lt;br /&gt;I may shortly in the future investigate this further, and perhaps we'll have a alternative if people want it for change tracking whilst disconnected.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-4903952670584093244?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/4903952670584093244/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=4903952670584093244' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/4903952670584093244'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/4903952670584093244'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2008/03/implementing-deletion-change-tracking.html' title='Implementing Disconnected Deletion Change Tracking'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-145906513474135999</id><published>2008-03-27T00:02:00.006+11:00</published><updated>2008-10-10T11:21:26.515+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linq to SQL Entity Base'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq to SQL'/><title type='text'>New Version of LINQ to SQL Entity Base Class (Beta 2.0)</title><content type='html'>Hi there!&lt;br /&gt;&lt;br /&gt;Just wanted everyone to know I've release a new version of the LINQ to SQL Entity base class.&lt;br /&gt;&lt;br /&gt;It now supports change tracking for deletes, as well as the ability to cascade delete.&lt;br /&gt;&lt;br /&gt;I guess from my point of view it's feature complete for ASP.NET use, assuming you store the entities in the session.&lt;br /&gt;&lt;br /&gt;Still have to work on serialization for WCF and other uses.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=LINQ2SQLEB&amp;amp;ReleaseId=11996"&gt;LINQ to SQL Entity Base Class Version 1.0 Beta 2.0&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Anyhow, check it out and let me know what you think.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Cheers&lt;br /&gt;&lt;br /&gt;Matthew Hunter&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-145906513474135999?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/145906513474135999/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=145906513474135999' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/145906513474135999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/145906513474135999'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2008/03/new-version-of-linq-to-sql-entity-base.html' title='New Version of LINQ to SQL Entity Base Class (Beta 2.0)'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-8395284375251603283</id><published>2008-03-14T21:51:00.006+11:00</published><updated>2008-10-10T11:22:06.654+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linq to SQL Entity Base'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq to SQL'/><title type='text'>Implementing Change Tracking when disconnected.</title><content type='html'>If you have a look at the LINQ to &lt;a href="http://www.codeplex.com/LINQ2SQLEB/SourceControl/ListDownloadableCommits.aspx"&gt;SQL Entity Base source code &lt;/a&gt;on codeplex, you'll see that the way I've implemented change tracking is by putting a few flags on the base class IsNew, IsModified, IsDeleted.&lt;br /&gt;&lt;br /&gt;I've been able to get IsNew &amp;amp; IsModified to set automacally, here's how they work:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;IsNew&lt;/strong&gt;&lt;br /&gt;This can be established by checking the entities RowVersion (TimeStamp) field (which BTW is a requirement to have for this to work). If the RowVersion is null, it's never been applied to the database (as the database sets this value not the developer) and hence we can tell with absolute certainty that it's a new object.&lt;br /&gt;&lt;em&gt;But it's in the child class how did I accomplish this? &lt;/em&gt;&lt;br /&gt;Since the RowVersion property is in the class, there's a few options we can use to achieve this:&lt;br /&gt;&lt;br /&gt;(1) Write extra code in the child entity class&lt;br /&gt;Nope, this is out of the question! We are trying to avoid coding here!&lt;br /&gt;&lt;br /&gt;(2) Create an interface (OK)&lt;br /&gt;This is probably the best action for performance, but you need to make sure that all entities use the same column name for the RowVersion. If you use this method, you could cast the current object to this an interface and get the value that way. Of course, to get the entity to implement this, you'll need to force it to implement the interface by adding it to the DataContext dbml file (just like &lt;a href="http://complexitykills.blogspot.com/2008/03/superclass-your-entities-without.html"&gt;described here&lt;/a&gt;) .&lt;br /&gt;However, as I'm writing something to share with one and all, and no doubt everyones gonna want to name it differently, this isn't the appropriate option (however it's still a damn good one!).&lt;br /&gt;&lt;br /&gt;(3) Use a virtual property and override it in the entity (OK)&lt;br /&gt;This is also good for performance, however it also means that you need to set every RowVersion field property property to have it's access modifier set to "override" which is a bit annoying. Personally I'm impressed that you can do this in the DBML model viewer, but it's still a little hard to maintain when you are adding tables - just another thing to remember, and again everthing has to be set to the same name for it to work.&lt;br /&gt;&lt;br /&gt;(4) Use reflection (OK)&lt;br /&gt;This is not so bad, we can simple get the properties using reflection and find which property is marked with ColumnAttribute.IsVersion = true. Seeing there can only be 1 of these per table (enforce by SQL Server) this is pretty safe. It also means i can throw a custom exception with a message if I discover that there is now RowVersion field and let the developer know.&lt;br /&gt;&lt;p&gt;So, after considering the options, I went with the later option being reflection mainly because it's the most flexible for this situation, but all things being equal I think the best option if you can control it is to use an interface as in (2) above.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;IsModified&lt;/strong&gt;&lt;br /&gt;This ones easy, there's already an interface supplied called &lt;span style="color:#3333ff;"&gt;INotifyPropertyChanged &lt;/span&gt;that each entity implements, which you can then use and attach to the childs &lt;span style="color:#3333ff;"&gt;PropertyChangedEventHandler&lt;/span&gt; in your parent class. Whenever this event is raised, we know a column has been changed and we know to set the IsModified Flag to true.&lt;br /&gt;Interestingly enough too, if the event is raised and it's the field that is the RowVersion (TimeStamp) property that's being updated, we know that the data has just been applied to the database, and hence we know we can reset the IsNew and IsModified and IsDeleted to false. So this is something we definately want to do, if after committing the data we want to keep working with our Entity Tree.&lt;br /&gt;One propblem is though, I noticed that this event is also raised for child entities and entity collections not just columns. I need to avoid these non-column events because they are not the type of property changes I am looking for. So, with a little reflection, I can find out if the property has an &lt;span style="color:#3333ff;"&gt;AssociationAttribue&lt;/span&gt; applied to it and ignore the change events raised for these. So that's solved too.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;IsDeleted&lt;/strong&gt;&lt;br /&gt;*** UPDATE --&gt; I've come up with a solution to this problem, &lt;a href="http://complexitykills.blogspot.com/2008/03/implementing-deletion-change-tracking.html"&gt;see this link for more details&lt;/a&gt; ***&lt;br /&gt;&lt;br /&gt;I'm still looking for a good way to do this. Unfortantely, the one draw back with the way the entities are organised when disconnected, is there's no good place to handle this because if you remove the entity, you remove the entity - it's gone - not much use setting a flag if you can no longer find it!&lt;br /&gt;&lt;br /&gt;One Idea I have is to store the object in the parent, but I haven't got around to working this one out. It's definately the trickiest of the lot.&lt;br /&gt;&lt;br /&gt;So for now, there's just a simple flag indicating that the object needs to be deleted, which is not ideal at this stage, but it mostly works, apart from where you have a single child entity (not a collection of entities) and you want to delete it and replace it with a diffent object - currenlty you have to commit to the database in between otherwise, again you'll loose the original object.&lt;br /&gt;&lt;br /&gt;Cheers&lt;br /&gt;&lt;br /&gt;Matt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-8395284375251603283?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/8395284375251603283/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=8395284375251603283' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/8395284375251603283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/8395284375251603283'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2008/03/implementing-change-tracking-when.html' title='Implementing Change Tracking when disconnected.'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-4081640820306488023</id><published>2008-03-14T20:45:00.004+11:00</published><updated>2008-10-10T11:22:22.842+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linq to SQL Entity Base'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq to SQL'/><title type='text'>Entity Base Project Added to Codeplex</title><content type='html'>For anyone that's interested, I've added an example project of some of the things I've found to codeplex and Called it the LINQ to SQL Entity Base.&lt;br /&gt;&lt;br /&gt;Check it out at the following Address:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.codeplex.com/LINQ2SQLEB"&gt;http://www.codeplex.com/LINQ2SQLEB&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It just demonstrates some change tracking, the entity tree enumeration feature and auto-syncing to the database.&lt;br /&gt;&lt;br /&gt;Anyway, go check it out if you want to see how some of these things I've found out can be put to use!&lt;br /&gt;&lt;br /&gt;Cheers&lt;br /&gt;&lt;br /&gt;Matt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-4081640820306488023?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/4081640820306488023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=4081640820306488023' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/4081640820306488023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/4081640820306488023'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2008/03/entity-base-codeplex-projec-added.html' title='Entity Base Project Added to Codeplex'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-112915656482690886</id><published>2008-03-13T22:14:00.024+11:00</published><updated>2008-10-10T11:22:55.183+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linq to SQL'/><title type='text'>Disconnected LINQ To SQL Tips Part 2</title><content type='html'>&lt;strong&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;How to Enumerate the Entity Tree Graph&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;I really, really like the way that the standard IEnumerator interface works, and in conjunction with "yield" keyword and a little, I came up with a cunning plan that would help me with my Disconnected model.&lt;br /&gt;&lt;br /&gt;Basically, I needed a way to find all objects that were changed tracked in an entity tree, otherwise it would be very manual and an awful lot of code to re-attach entity. It's not so much of a problem when you have just a parent and some children like so:&lt;br /&gt;&lt;br /&gt;Customer1&lt;br /&gt;-&gt; Order1&lt;br /&gt;-&gt; Order2&lt;br /&gt;-&gt; Order3&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here you could just re-attach you're objects, first with the custmer and then in a nice little loop attch the orders.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This will be fairly light and not a lot of code, but I thought that in a lot of circumstances the tree would be a lot more complicated like this:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Customer1&lt;br /&gt;-&gt; Order1&lt;br /&gt;-&gt;-&gt;OrderDetails1&lt;br /&gt;-&gt;-&gt;OrderDetails2&lt;br /&gt;-&gt; Order2&lt;br /&gt;-&gt;-&gt;OrderDetails3&lt;br /&gt;-&gt;-&gt;OrderDetails4&lt;br /&gt;-&gt;Order3&lt;br /&gt;-&gt;Order4&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This starts to look a little complicated because now you have to write a lot of code that loops through each level of the tree attaching as necessary... and you can start to imagine trees that may be 20 entities deep and all of the place. Yuk.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So, basically with a little help from reflection and with the use of the base class, I could put togther a nice little function that would traverse the enitre tree in one list. This is useful for a lot of reasons, not just for finding changed objects, but you would now have the ability to find an object or objects in the tree without hardcoding paths in your linq statements.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Of course, I've only done parent-&gt;child relationships and ignore foriegn key ones (Child &lt;- Parent) to avoid overflowing the stack. &lt;p&gt;This code is in the base class for all entities that will allow you to enumerate against a tree of entities. Please note the following:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Yes, it will work in connected mode as well, i.e. when a datacontext is attached.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You can query it with LINQ &lt;/li&gt;&lt;br /&gt;&lt;li&gt;-&gt; var temp = from c in customer.GetEntityHierarchy().OfType&lt;order&gt;() select c);&lt;br /&gt;&lt;/li&gt;&lt;li&gt;If you're wondering why I've put it in a private class instead of just exposing IEnumerator/IEnumerable on the entity it's self - it's because at runtime it seems to fail because I think Microsoft have put some sort of runtime check on it, perhaps because they want to reserve the IEnumerator for implementation later on.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Data.Linq;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Data.Linq.Mapping;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Text;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.ComponentModel;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Runtime.Serialization;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Reflection;&lt;/pre&gt;&lt;pre class="alt"&gt; &lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; LINQEntityBaseExample1&lt;/pre&gt;&lt;pre class="alt"&gt;{&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; LINQEntityBase&lt;/pre&gt;&lt;pre class="alt"&gt;    {&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;// stores the property info for associations&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, PropertyInfo&amp;gt; _entityAssociationProperties &lt;/pre&gt;&lt;pre&gt;                    = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, PropertyInfo&amp;gt;(); &lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//used to hold the private class that allows entity hierarchy to be enumerated&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; EntityHierarchy _entityHierarchy; &lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;/// Constructor!&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;protected&lt;/span&gt; LINQEntityBase()&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;// Note: FindAssociations() finds association property info's &lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="rem"&gt;// using reflection (where IsForeignKey !=true)&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;// Have left this function out just to keep this short.&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            _entityAssociationProperties = FindAssociations();&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;// pass in the current object and it's property associations&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            _entityHierarchy = &lt;span class="kwrd"&gt;new&lt;/span&gt; EntityHierarchy(&lt;span class="kwrd"&gt;this&lt;/span&gt;, _entityAssociationProperties);&lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;/// This method flattens the hierachy of objects into a single list that can be queried by linq&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; IEnumerable&amp;lt;LINQEntityBase&amp;gt; GetEntityHierarchy()&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; (from t &lt;span class="kwrd"&gt;in&lt;/span&gt; _entityHierarchy&lt;/pre&gt;&lt;pre&gt;                    select t);&lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;/// This class is used internally to implement IEnumerable, so that the hierarchy can&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;/// be enumerated by LINQ queries.&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; EntityHierarchy : IEnumerable&amp;lt;LINQEntityBase&amp;gt;&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;private&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, PropertyInfo&amp;gt; _entityAssociationProperties;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;private&lt;/span&gt; LINQEntityBase _entityRoot;&lt;/pre&gt;&lt;pre class="alt"&gt; &lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;public&lt;/span&gt; EntityHierarchy(LINQEntityBase EntityRoot, Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, PropertyInfo&amp;gt; EntityAssociationProperties)&lt;/pre&gt;&lt;pre class="alt"&gt;            {&lt;/pre&gt;&lt;pre&gt;                _entityRoot = EntityRoot;&lt;/pre&gt;&lt;pre class="alt"&gt;                _entityAssociationProperties = EntityAssociationProperties;&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class="alt"&gt; &lt;/pre&gt;&lt;pre&gt;            &lt;span class="rem"&gt;// implement the GetEnumerator Type&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;public&lt;/span&gt; IEnumerator&amp;lt;LINQEntityBase&amp;gt; GetEnumerator()&lt;/pre&gt;&lt;pre&gt;            {&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="rem"&gt;// return the current object&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                &lt;span class="kwrd"&gt;yield&lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; _entityRoot;&lt;/pre&gt;&lt;pre class="alt"&gt; &lt;/pre&gt;&lt;pre&gt;                &lt;span class="rem"&gt;// return the children (using reflection)&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (PropertyInfo propInfo &lt;span class="kwrd"&gt;in&lt;/span&gt; _entityAssociationProperties.Values)&lt;/pre&gt;&lt;pre&gt;                {&lt;/pre&gt;&lt;pre class="alt"&gt;                    &lt;span class="rem"&gt;// Is it an EntitySet&amp;lt;&amp;gt; ?&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (propInfo.PropertyType.IsGenericType &amp;amp;&amp;amp; propInfo.PropertyType.GetGenericTypeDefinition() == &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(EntitySet&amp;lt;&amp;gt;))&lt;/pre&gt;&lt;pre class="alt"&gt;                    {&lt;/pre&gt;&lt;pre&gt;                        &lt;span class="rem"&gt;// It's an EntitySet&amp;lt;&amp;gt; so lets grab the value, loop through each value and&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                        &lt;span class="rem"&gt;// return each value as an EntityBase.&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                        IEnumerator entityList = (propInfo.GetValue(_entityRoot, &lt;span class="kwrd"&gt;null&lt;/span&gt;) &lt;span class="kwrd"&gt;as&lt;/span&gt; IEnumerable).GetEnumerator();&lt;/pre&gt;&lt;pre class="alt"&gt; &lt;/pre&gt;&lt;pre&gt;                        &lt;span class="kwrd"&gt;while&lt;/span&gt; (entityList.MoveNext() == &lt;span class="kwrd"&gt;true&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alt"&gt;                        {&lt;/pre&gt;&lt;pre&gt;                            &lt;span class="kwrd"&gt;if&lt;/span&gt; (entityList.Current.GetType().IsSubclassOf(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(LINQEntityBase)))&lt;/pre&gt;&lt;pre class="alt"&gt;                            {&lt;/pre&gt;&lt;pre&gt;                                LINQEntityBase currentEntity = (LINQEntityBase)entityList.Current;&lt;/pre&gt;&lt;pre class="alt"&gt;                                &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (LINQEntityBase subEntity &lt;span class="kwrd"&gt;in&lt;/span&gt; currentEntity.GetEntityHierarchy())&lt;/pre&gt;&lt;pre&gt;                                {&lt;/pre&gt;&lt;pre class="alt"&gt;                                    &lt;span class="kwrd"&gt;yield&lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; subEntity;&lt;/pre&gt;&lt;pre&gt;                                }&lt;/pre&gt;&lt;pre class="alt"&gt;                            }&lt;/pre&gt;&lt;pre&gt;                        }&lt;/pre&gt;&lt;pre class="alt"&gt;                    }&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (propInfo.PropertyType.IsSubclassOf(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(LINQEntityBase)))&lt;/pre&gt;&lt;pre class="alt"&gt;                    {&lt;/pre&gt;&lt;pre&gt;                        &lt;span class="rem"&gt;//Ask for these children for their section of the tree.&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (LINQEntityBase subEntity &lt;span class="kwrd"&gt;in&lt;/span&gt; (propInfo.GetValue(_entityRoot, &lt;span class="kwrd"&gt;null&lt;/span&gt;) &lt;span class="kwrd"&gt;as&lt;/span&gt; LINQEntityBase).GetEntityHierarchy())&lt;/pre&gt;&lt;pre&gt;                        {&lt;/pre&gt;&lt;pre class="alt"&gt;                            &lt;span class="kwrd"&gt;yield&lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; subEntity;&lt;/pre&gt;&lt;pre&gt;                        }&lt;/pre&gt;&lt;pre class="alt"&gt;                    }&lt;/pre&gt;&lt;pre&gt;                }&lt;/pre&gt;&lt;pre class="alt"&gt;            }&lt;/pre&gt;&lt;pre&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;// implement the GetEnumerator type&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            IEnumerator IEnumerable.GetEnumerator()&lt;/pre&gt;&lt;pre class="alt"&gt;            {&lt;/pre&gt;&lt;pre&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.GetEnumerator();&lt;/pre&gt;&lt;pre class="alt"&gt;            }&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class="alt"&gt; &lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt; &lt;/pre&gt;&lt;pre&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-112915656482690886?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/112915656482690886/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=112915656482690886' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/112915656482690886'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/112915656482690886'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2008/03/how-to-enumerator-linq-to-sql-object.html' title='Disconnected LINQ To SQL Tips Part 2'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-7141019190349379714</id><published>2008-03-04T17:59:00.000+11:00</published><updated>2008-03-04T18:09:27.311+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linq to SQL'/><title type='text'>Superclass your entities without using SQLMetal</title><content type='html'>&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Superclass your entities without using SQLMetal&lt;/span&gt;&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;Often I look through posts and find that people are repeating a lot of code in partial classes, when some of this work could be done in a parent class. The only documented way to do this seems to be the SQLMetal.exe command line tool. However, it's entirely possible to do this without SQLMetal.exe. To make this possible, it's just a simple matter of using notepad to edit your existing dbml file and adding the following to the "Database" element:&lt;br /&gt;&lt;br /&gt;EntityBase="[EntityBase]"&lt;br /&gt;&lt;br /&gt;Where [EntityBase] can be replaced with the name of your superclass.&lt;br /&gt;&lt;br /&gt;Next, save the file and go back to your project. Right click on the DBML file in the VS project and select "Run custom tool"... the next thing you know all your LINQ to SQL objects will be subclasses to what you specified.&lt;br /&gt;&lt;br /&gt;You can update this anytime, without screwing anything up... and the way it does it is pretty lazy...There's no checking of any sort, so you can prefix your class with a namespace, add multiple interfaces or just have your entities implement an interface without a base class.&lt;br /&gt;&lt;br /&gt;E.g.&lt;br /&gt;&lt;br /&gt;EntityBase="Sample.EntityBase"&lt;br /&gt;EntityBase="Sample.EntityBase, IMyInterface1, IMyInterface2"&lt;br /&gt;EntityBase="IMyInterface"&lt;br /&gt;&lt;br /&gt;Anyway, I've already used this for a number of reasons - quite useful.&lt;br /&gt;&lt;br /&gt;Cheers&lt;br /&gt;&lt;br /&gt;Matt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-7141019190349379714?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/7141019190349379714/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=7141019190349379714' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/7141019190349379714'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/7141019190349379714'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2008/03/superclass-your-entities-without.html' title='Superclass your entities without using SQLMetal'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6070382805242147283.post-2833003218718662605</id><published>2008-03-03T23:55:00.001+11:00</published><updated>2008-03-14T20:44:43.235+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linq to SQL'/><title type='text'>Disconnected LINQ to SQL Tips Part 1</title><content type='html'>&lt;span style="font-size:180%;"&gt;Intro! &lt;/span&gt;&lt;br /&gt;In my research on LINQ to SQL and trying to work around the limititation of no "out of the box" disconnected (n-tier) mode, I've come accross a lot of things that others may find useful.&lt;br /&gt;&lt;br /&gt;I was somewhat disappointed in this drawback as LINQ to SQL - seeing that it was only intended to be used in "connected" scenario. I saw it as a challenge to figure out ways in which a "disconnected" scenario could be done.&lt;br /&gt;&lt;br /&gt;Hence, here I am a first time virgin blogger - who felt compelled to reduce the sweat and tears of others while dealing with this double edged sword.&lt;br /&gt;&lt;br /&gt;I'll be blogging how "Disconnected LINQ" can be achieved in a later post, but first up here's some tips for some of you out there that might be struggling with "Disconnected LINQ".&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;The 'How to do Disconnected' Rules&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;First up, here are the rules for allowing disconnected LINQ to SQL. To successfully disconnect a LINQ to SQL entity from a Data Context and allow it to re-connect to a different Data Context, you must do the following:&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;1. Enable Concurrency Tracking &lt;/strong&gt;&lt;br /&gt;You can enable concurrency tracking by adding a timestamp (rowversion) field to your database and include this in your LINQ to SQL model.&lt;br /&gt;&lt;br /&gt;Alternatively, if you don't care for concurrency tracking you can set all columns so that the Update Check is set to false.&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;2. Disable Deffered Loading, Load Everything or Serialize the objects&lt;/strong&gt;&lt;br /&gt;Disabling Lazy loading is fairly straight forward, it just a simple matter of setting the DeferredLoadingEnabled = False like so:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; (EntitiesDataContext db = &lt;span class="kwrd"&gt;new&lt;/span&gt; EntitiesDataContext())&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class="alt"&gt;    db.DeferredLoadingEnabled = &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;    var customers = from c &lt;span class="kwrd"&gt;in&lt;/span&gt; db.Customers&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="kwrd"&gt;where&lt;/span&gt; c.CustomerId == CustomerId&lt;/pre&gt;&lt;pre class="alt"&gt;                    select c;&lt;/pre&gt;&lt;pre&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;This tells link not to query that database when a link association (another object or collection) is referenced, instead it will simply return a null.&lt;br /&gt;&lt;br /&gt;Alternatively, you can also load all related objects so there is nothing to lazy load. This can be done by using the datacontext load options object like so:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; (EntitiesDataContext db = &lt;span class="kwrd"&gt;new&lt;/span&gt; EntitiesDataContext())&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class="alt"&gt;    DataLoadOptions lo = &lt;span class="kwrd"&gt;new&lt;/span&gt; DataLoadOptions();&lt;/pre&gt;&lt;pre&gt;    lo.LoadWith&amp;lt;Customer&amp;gt;(c =&amp;gt; c.Dependants);&lt;/pre&gt;&lt;pre class="alt"&gt;    db.LoadOptions = lo;&lt;/pre&gt;&lt;pre&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;    var customers = from c &lt;span class="kwrd"&gt;in&lt;/span&gt; db.Customers&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="kwrd"&gt;where&lt;/span&gt; c.CustomerId == CustomerId&lt;/pre&gt;&lt;pre class="alt"&gt;                    select c;&lt;/pre&gt;&lt;pre&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;Basically, this is telling the data context that whenever it loads a Customer, it should also load the Dependants for that customer. If all the related objects or collections are covered in this way, LINQ to SQL won't even consider deferred loading because it believes it has all the possible connected objects.&lt;br /&gt;&lt;br /&gt;As for serialization, this automatically disables deferred loading as above ... and how to serialize is covered next....&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Serializing and copying the objects&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;Linq to SQL entities cannot be serialized using standard serialization techniques, this means you can't just pop it in the view state or ASP.NET state server without running into some trouble.&lt;br /&gt;&lt;br /&gt;In order to serialize an LINQ to SQL object graph (a root object and it's child entities) you'll need to use the WCF data contract serializer instead.&lt;br /&gt;&lt;br /&gt;But wait! Even before you do that, you'll need to set your Data Contexts serialization mode to "Unidirectional" (which is available in the model properties). This means that only references in the object graph from parent to child will be serialized and therefore therefore child to parent references will be ignored. This is good because it means that circular references won't cause problems. The standard serializer can't be used for exactly this reason, because it would end up with failing because it would try to serialize circular references.&lt;br /&gt;&lt;br /&gt;Here's a couple of functions which can be used to serialize/deserialize a LINQ to SQL object graph and also a handy copy function which will make a completely seperate copy of an object graph.&lt;br /&gt;&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Runtime.Serialization;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Text;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Xml;&lt;/pre&gt;&lt;pre&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; SampleFramework&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; LINQHelper&lt;/pre&gt;&lt;pre&gt;    {       &lt;/pre&gt;&lt;pre class="alt"&gt; &lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;/// Makes a copy of an existing LINQ to SQL entity and it's children.&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;/// &amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;/// &amp;lt;param name="entitySource"&amp;gt;The LINQ to SQL entity to copy&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; T CopyEntityDeep&amp;lt;T&amp;gt;(T entitySource)&lt;/pre&gt;&lt;pre class="alt"&gt;        {&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (entitySource == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;default&lt;/span&gt;(T);&lt;/pre&gt;&lt;pre&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; (T)DeserializeEntity(SerializeEntity(entitySource), entitySource.GetType());&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class="alt"&gt; &lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;/// Makes a copy of a list of existing LINQ to SQL entities and their children.&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;/// &amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;/// &amp;lt;param name="source"&amp;gt;The LIST of SQL entities to copy&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;/// &amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; List&amp;lt;T&amp;gt; CopyEntityListDeep&amp;lt;T&amp;gt;(List&amp;lt;T&amp;gt; entitySourceList)&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;            List&amp;lt;T&amp;gt; result = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;T&amp;gt;();&lt;/pre&gt;&lt;pre&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (entitySourceList == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;&lt;pre&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="alt"&gt; &lt;/pre&gt;&lt;pre&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (T entitySource &lt;span class="kwrd"&gt;in&lt;/span&gt; entitySourceList)&lt;/pre&gt;&lt;pre&gt;            {&lt;/pre&gt;&lt;pre class="alt"&gt;                T entityTarget = CopyEntityDeep(entitySource);&lt;/pre&gt;&lt;pre&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;                result.Add(entityTarget);&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class="alt"&gt; &lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; result;&lt;/pre&gt;&lt;pre class="alt"&gt; &lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class="alt"&gt;     &lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; SerializeEntity&amp;lt;T&amp;gt;(T entitySource)&lt;/pre&gt;&lt;pre class="alt"&gt;        {&lt;/pre&gt;&lt;pre&gt;            DataContractSerializer dcs = &lt;span class="kwrd"&gt;new&lt;/span&gt; DataContractSerializer(entitySource.GetType());&lt;/pre&gt;&lt;pre class="alt"&gt; &lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (entitySource == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;            StringBuilder sb = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder();&lt;/pre&gt;&lt;pre&gt;            XmlWriter xmlw = XmlWriter.Create(sb);&lt;/pre&gt;&lt;pre class="alt"&gt;            dcs.WriteObject(xmlw, entitySource);&lt;/pre&gt;&lt;pre&gt;            xmlw.Close();&lt;/pre&gt;&lt;pre class="alt"&gt; &lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; sb.ToString();&lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; DeserializeEntity(&lt;span class="kwrd"&gt;string&lt;/span&gt; entitySource, Type entityType)&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;object&lt;/span&gt; entityTarget;&lt;/pre&gt;&lt;pre&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (entityType == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;&lt;pre&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="alt"&gt; &lt;/pre&gt;&lt;pre&gt;            DataContractSerializer dcs = &lt;span class="kwrd"&gt;new&lt;/span&gt; DataContractSerializer(entityType);&lt;/pre&gt;&lt;pre class="alt"&gt; &lt;/pre&gt;&lt;pre&gt;            StringReader sr = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringReader(entitySource);&lt;/pre&gt;&lt;pre class="alt"&gt;            XmlTextReader xmltr = &lt;span class="kwrd"&gt;new&lt;/span&gt; XmlTextReader(sr);&lt;/pre&gt;&lt;pre&gt;            entityTarget = (&lt;span class="kwrd"&gt;object&lt;/span&gt;)dcs.ReadObject(xmltr);&lt;/pre&gt;&lt;pre class="alt"&gt;            xmltr.Close();&lt;/pre&gt;&lt;pre&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; entityTarget;&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class="alt"&gt;    }&lt;/pre&gt;&lt;pre&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Wrapping up&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;Next post, I hope to move further into the disconnected model that I've come up with that uses some of the above techniques to track changes.&lt;br /&gt;&lt;br /&gt;Cheers&lt;br /&gt;&lt;br /&gt;Matt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6070382805242147283-2833003218718662605?l=complexitykills.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://complexitykills.blogspot.com/feeds/2833003218718662605/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6070382805242147283&amp;postID=2833003218718662605' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/2833003218718662605'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6070382805242147283/posts/default/2833003218718662605'/><link rel='alternate' type='text/html' href='http://complexitykills.blogspot.com/2008/03/disconnected-linq-to-sql-tips-part-1.html' title='Disconnected LINQ to SQL Tips Part 1'/><author><name>Matthew Hunter</name><uri>http://www.blogger.com/profile/15449365892205165530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry></feed>
