<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.2.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>Rizal Almashoor's Blog</title>
	<link>http://www.rizalalmashoor.com/blog</link>
	<description>Valid use of Null</description>
	<pubDate>Tue, 17 Jan 2012 08:31:16 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.2.2</generator>
	<language>en</language>
			<item>
		<title>Calling an Oracle function using NHibernate</title>
		<link>http://www.rizalalmashoor.com/blog/calling-an-oracle-function-using-nhibernate/</link>
		<comments>http://www.rizalalmashoor.com/blog/calling-an-oracle-function-using-nhibernate/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 08:31:16 +0000</pubDate>
		<dc:creator>Rizal Almashoor</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.rizalalmashoor.com/blog/calling-an-oracle-function-using-nhibernate/</guid>
		<description><![CDATA[
Tested with NHibernate 2.1.2 and Oracle 11g.
Needs Oracle.DataAccess (not System.Data.OracleClient). Tested with Oracle.DataAccess 2.111.6.0 AMD64.
If your Oracle function returns a scalar value of datatype number, the .NET object will be a Decimal.

NHibernate config:

&#60;hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"&#62;
  &#60;session-factory&#62;
    &#60;property name="connection.driver_class"&#62;
      NHibernate.Driver.OracleDataClientDriver
    &#60;/property&#62;
  &#60;/session-factory&#62;
&#60;/hibernate-configuration&#62;

C# code:

var result [...]]]></description>
			<content:encoded><![CDATA[<ol>
<li>Tested with NHibernate 2.1.2 and Oracle 11g.</li>
<li>Needs Oracle.DataAccess (not System.Data.OracleClient). Tested with Oracle.DataAccess 2.111.6.0 AMD64.</li>
<li>If your Oracle function returns a scalar value of datatype number, the .NET object will be a Decimal.</li>
</ol>
<p>NHibernate config:</p>
<pre class="brush: xml">
&lt;hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"&gt;
  &lt;session-factory&gt;
    &lt;property name="connection.driver_class"&gt;
      NHibernate.Driver.OracleDataClientDriver
    &lt;/property&gt;
  &lt;/session-factory&gt;
&lt;/hibernate-configuration&gt;
</pre>
<p>C# code:</p>
<pre class="brush: csharp">
var result = nhibernateSession
    .CreateSQLQuery("select GetSomeValue(:p_parameter1) from dual")
    .SetParameter("p_parameter1", parameter1)
    .UniqueResult();

// GetSomeValue returns a scalar of datatype number; result will be object of type Decimal

var someValue = Convert.ToInt32(result);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.rizalalmashoor.com/blog/calling-an-oracle-function-using-nhibernate/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Calling an Oracle stored procedure using NHibernate</title>
		<link>http://www.rizalalmashoor.com/blog/calling-an-oracle-stored-procedure-using-nhibernate/</link>
		<comments>http://www.rizalalmashoor.com/blog/calling-an-oracle-stored-procedure-using-nhibernate/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 08:16:41 +0000</pubDate>
		<dc:creator>Rizal Almashoor</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://www.rizalalmashoor.com/blog/calling-an-oracle-stored-procedure-using-nhibernate/</guid>
		<description><![CDATA[
The stored procedure must have an out sys_refcursor parameter as the first argument.
Tested with NHibernate 2.1.2 and Oracle 11g.
Needs Oracle.DataAccess (not System.Data.OracleClient). Tested with Oracle.DataAccess 2.111.6.0 AMD64.

NHibernate config:

&#60;hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"&#62;
  &#60;session-factory&#62;
    &#60;property name="connection.driver_class"&#62;
      NHibernate.Driver.OracleDataClientDriver
    &#60;/property&#62;
  &#60;/session-factory&#62;
&#60;/hibernate-configuration&#62;

NHibernate mapping:

&#60;hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SampleProject" namespace="SampleProject"&#62;
  &#60;sql-query name="GetEmployeesByDepartmentId"&#62;
 [...]]]></description>
			<content:encoded><![CDATA[<ol>
<li>The stored procedure must have an out <strong>sys_refcursor</strong> parameter as the <strong>first</strong> argument.</li>
<li>Tested with NHibernate 2.1.2 and Oracle 11g.</li>
<li>Needs Oracle.DataAccess (not System.Data.OracleClient). Tested with Oracle.DataAccess 2.111.6.0 AMD64.</li>
</ol>
<p>NHibernate config:</p>
<pre class="brush: xml">
&lt;hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"&gt;
  &lt;session-factory&gt;
    &lt;property name="connection.driver_class"&gt;
      NHibernate.Driver.OracleDataClientDriver
    &lt;/property&gt;
  &lt;/session-factory&gt;
&lt;/hibernate-configuration&gt;
</pre>
<p>NHibernate mapping:</p>
<pre class="brush: xml">
&lt;hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SampleProject" namespace="SampleProject"&gt;
  &lt;sql-query name="GetEmployeesByDepartmentId"&gt;
    &lt;return class="Employee" /&gt;
    { call GetEmployeesByDepartmentId(:p_departmentid) }
  &lt;/sql-query&gt;
&lt;/hibernate-mapping&gt;
</pre>
<p>C# code:</p>
<pre class="brush: csharp">
var employees = nhibernateSession
    .GetNamedQuery("GetEmployeesByDepartmentId")
    .SetParameter("p_departmentid", departmentId)
    .List&lt;Employee&gt;();
</pre>
<p>To execute a stored procedure that has no out parameters:</p>
<pre class="brush: csharp">
nhibernateSession
    .CreateSQLQuery("call DoSomething(:p_parameter1)")
    .SetParameter("p_parameter1", parameter1)
    .ExecuteUpdate();
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.rizalalmashoor.com/blog/calling-an-oracle-stored-procedure-using-nhibernate/feed/</wfw:commentRss>
		</item>
		<item>
		<title>LINQPad &#8211; a worthy successor to Snippet Compiler</title>
		<link>http://www.rizalalmashoor.com/blog/linqpad-a-worthy-successor-to-snippet-compiler/</link>
		<comments>http://www.rizalalmashoor.com/blog/linqpad-a-worthy-successor-to-snippet-compiler/#comments</comments>
		<pubDate>Fri, 05 Aug 2011 10:03:15 +0000</pubDate>
		<dc:creator>Rizal Almashoor</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Applications]]></category>

		<guid isPermaLink="false">http://www.rizalalmashoor.com/blog/linqpad-a-worthy-successor-to-snippet-compiler/</guid>
		<description><![CDATA[In 2009 I blogged about how Snippet Compiler allows us to test out C# code without having to create a project in Visual Studio just for that. Now there&#8217;s something better: LINQPad. Don&#8217;t be misled by its name; it&#8217;s not just for LINQ, it can run any C#, VB, or even SQL code. I particularly [...]]]></description>
			<content:encoded><![CDATA[<p>In 2009 I <a href="http://www.rizalalmashoor.com/blog/snippet-compiler">blogged</a> about how <a href="http://www.sliver.com/dotnet/SnippetCompiler/">Snippet Compiler</a> allows us to test out C# code without having to create a project in Visual Studio just for that. Now there&#8217;s something better: <a href="http://www.linqpad.net">LINQPad</a>. Don&#8217;t be misled by its name; it&#8217;s not just for LINQ, it can run any C#, VB, or even SQL code. I particularly like its results view. A screenshot is worth a thousand words:</p>
<p><img src="http://www.linqpad.net/linqpadscreen.png" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.rizalalmashoor.com/blog/linqpad-a-worthy-successor-to-snippet-compiler/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Problem with Transactions on Windows 64-bit Oracle Client</title>
		<link>http://www.rizalalmashoor.com/blog/problem-with-transactions-on-windows-64-bit-oracle-client/</link>
		<comments>http://www.rizalalmashoor.com/blog/problem-with-transactions-on-windows-64-bit-oracle-client/#comments</comments>
		<pubDate>Wed, 03 Aug 2011 04:56:25 +0000</pubDate>
		<dc:creator>Rizal Almashoor</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.rizalalmashoor.com/blog/problem-with-transactions-on-windows-64-bit-oracle-client/</guid>
		<description><![CDATA[After upgrading to a 64-bit machine at the office, my Visual Studio 2010 unit tests that were making heavy use of transactions (i.e., hundreds of uncommitted database table insertions within a using (new TransactionScope()) statement) failed with the following error message:
ORA-00603: ORACLE server session terminated by fatal error
ORA-00600: internal error code, arguments: [ktcirs:hds], [0&#215;00F7D8078], [0&#215;006F10BF0], [...]]]></description>
			<content:encoded><![CDATA[<p>After upgrading to a 64-bit machine at the office, my Visual Studio 2010 unit tests that were making heavy use of transactions (i.e., hundreds of uncommitted database table insertions within a <code>using (new TransactionScope())</code> statement) failed with the following error message:</p>
<p><code>ORA-00603: ORACLE server session terminated by fatal error<br />
ORA-00600: internal error code, arguments: [ktcirs:hds], [0&#215;00F7D8078], [0&#215;006F10BF0], [0&#215;01B8C8078], [], [], [], [], [], [], [], []<br />
ORA-00600: internal error code, arguments: [ktcirs:hds], [0&#215;00F7D8078], [0&#215;006F10BF0], [0&#215;01B8C8078], [], [], [], [], [], [], [], []<br />
Process ID: 4084<br />
Session ID: 125 Serial number: 369</code></p>
<h4>The solution</h4>
<ol>
<li>Install 64-bit Oracle Client 11.1.0.6.0 (<code><a href="http://www.oracle.com/technetwork/database/enterprise-edition/downloads/111060-win64soft-099656.html">win64_11gR1_client.zip</a></code>) but do <strong>not</strong> install Oracle Services for Microsoft Transaction Server.</li>
<li>Install <strong>only</strong> OraMTS using 64-bit Oracle Data Access Component 11.2.0.2.1 (<code><a href="http://www.oracle.com/technetwork/database/windows/downloads/index-090165.html">ODAC112021Xcopy_x64.zip</a></code>).</li>
</ol>
<h4>What&#8217;s the problem, BTW?</h4>
<p>&#8220;Windows Vista and Windows Server 2008 introduce new MSDTC changes that do not interoperate with older versions of Oracle Services for MTS. Oracle Services for MTS 10.2.0.4 and higher, <strong>with the exception of 11.1.0.6</strong>, support these new changes on Windows Vista Service Pack 1 and Windows Server 2008 or higher.&#8221; Source: <a href="http://www.oracle.com/technetwork/database/windows/index-089915.html">http://www.oracle.com/technetwork/database/windows/index-089915.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.rizalalmashoor.com/blog/problem-with-transactions-on-windows-64-bit-oracle-client/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Robocopy in lieu of rsync</title>
		<link>http://www.rizalalmashoor.com/blog/robocopy-in-lieu-of-rsync/</link>
		<comments>http://www.rizalalmashoor.com/blog/robocopy-in-lieu-of-rsync/#comments</comments>
		<pubDate>Tue, 01 Feb 2011 05:59:45 +0000</pubDate>
		<dc:creator>Rizal Almashoor</dc:creator>
		
		<category><![CDATA[LAMP]]></category>

		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.rizalalmashoor.com/blog/robocopy-in-lieu-of-rsync/</guid>
		<description><![CDATA[Perhaps you’re a web developer familiar with Linux and SVN. Then you’ll definitely know how to copy files from your SVN working directory to a test server whilst excluding all .svn directories:
rsync -IrW --stats --exclude=.svn /path/to/project/dir/ //testsrv/whatever
If for some reason your development environment is Windows you might be tempted to use rsync on Cygwin. That’s [...]]]></description>
			<content:encoded><![CDATA[<p>Perhaps you’re a web developer familiar with Linux and SVN. Then you’ll definitely know how to copy files from your SVN working directory to a test server whilst excluding all .svn directories:</p>
<p><code>rsync -IrW --stats --exclude=.svn /path/to/project/dir/ //testsrv/whatever</code></p>
<p>If for some reason your development environment is Windows you might be tempted to use rsync on Cygwin. That’s works fine (albeit with a very noticeable performance lag), but there is actually a native Windows alternative to rsync:</p>
<p><code>robocopy \path\to\project\dir \\testsrv\whatever /MIR /XD .svn</code></p>
<p>Robocopy has long been available on NT 4.0 via the Windows Resource Kit, and is included in Vista, Windows 7, and Windows Server 2008.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rizalalmashoor.com/blog/robocopy-in-lieu-of-rsync/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Memories of the past</title>
		<link>http://www.rizalalmashoor.com/blog/memories-of-the-past/</link>
		<comments>http://www.rizalalmashoor.com/blog/memories-of-the-past/#comments</comments>
		<pubDate>Sat, 08 Jan 2011 16:01:46 +0000</pubDate>
		<dc:creator>Rizal Almashoor</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.rizalalmashoor.com/blog/memories-of-the-past/</guid>
		<description><![CDATA[The past doesn&#8217;t exist, except in our minds. There is not one past, but many pasts, each belonging to a different person.
If not for memory, there would be no such thing as the past. It is literally all in the mind.
Easy enough to comprehend, but extremely difficult to internalize.
]]></description>
			<content:encoded><![CDATA[<p>The past doesn&#8217;t exist, except in our minds. There is not one past, but many pasts, each belonging to a different person.</p>
<p>If not for memory, there would be no such thing as the past. It is literally all in the mind.</p>
<p>Easy enough to comprehend, but extremely difficult to internalize.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rizalalmashoor.com/blog/memories-of-the-past/feed/</wfw:commentRss>
		</item>
		<item>
		<title>A fundamentally flawed argument</title>
		<link>http://www.rizalalmashoor.com/blog/a-fundamentally-flawed-argument/</link>
		<comments>http://www.rizalalmashoor.com/blog/a-fundamentally-flawed-argument/#comments</comments>
		<pubDate>Fri, 07 Jan 2011 21:38:43 +0000</pubDate>
		<dc:creator>Rizal Almashoor</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.rizalalmashoor.com/blog/a-fundamentally-flawed-argument/</guid>
		<description><![CDATA[I believe that everyone has at least one fundamental flaw. Those who think they aren&#8217;t fundamentally flawed turn out to have three fundamental flaws: first, their fundamental flaw; second, their ignorance of their fundamental flaw; and third, their belief that they are free of fundamental flaws.
The least fundamentally flawed are those armed with full knowledge [...]]]></description>
			<content:encoded><![CDATA[<p>I believe that everyone has at least one fundamental flaw. Those who think they aren&#8217;t fundamentally flawed turn out to have three fundamental flaws: first, their fundamental flaw; second, their ignorance of their fundamental flaw; and third, their belief that they are free of fundamental flaws.</p>
<p>The least fundamentally flawed are those armed with full knowledge of exactly how much and in what way they are fundamentally flawed. Inhabiting unhappy middle ground would be those who are aware that they&#8217;re fundamentally flawed, but now how so.</p>
<p>If it is indeed possible not to be fundamentally flawed, then that would be the biggest fundamental flaw of all.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rizalalmashoor.com/blog/a-fundamentally-flawed-argument/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Implementing the right-click context menu in Silverlight 4</title>
		<link>http://www.rizalalmashoor.com/blog/implementing-the-right-click-context-menu-in-silverlight-4/</link>
		<comments>http://www.rizalalmashoor.com/blog/implementing-the-right-click-context-menu-in-silverlight-4/#comments</comments>
		<pubDate>Tue, 16 Nov 2010 03:58:55 +0000</pubDate>
		<dc:creator>Rizal Almashoor</dc:creator>
		
		<category><![CDATA[Silverlight]]></category>

		<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://www.rizalalmashoor.com/blog/implementing-the-right-click-context-menu-in-silverlight-4/</guid>
		<description><![CDATA[
Download and install Silverlight 4 Toolkit - April 2010.
In your Silverlight 4 project, add references to:

System.Windows.Controls
System.Windows.Controls.Input.Toolkit

In your UserControl XAML, add the following to the LayoutRoot grid opening tag: MouseRightButtonDown="LayoutRoot_MouseRightButtonDown" MouseRightButtonUp="LayoutRoot_MouseRightButtonUp"
In the codebehind:


using System.Windows.Controls;

...

private void LayoutRoot_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
    e.Handled = true;
}

private void LayoutRoot_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
    var contextMenu = [...]]]></description>
			<content:encoded><![CDATA[<ol>
<li>Download and install <a href="http://silverlight.codeplex.com/releases/view/43528">Silverlight 4 Toolkit - April 2010</a>.</li>
<li>In your Silverlight 4 project, add references to:
<ul>
<li><code>System.Windows.Controls</code></li>
<li><code>System.Windows.Controls.Input.Toolkit</code></li>
</ul>
<li>In your UserControl XAML, add the following to the LayoutRoot grid opening tag: <code>MouseRightButtonDown="LayoutRoot_MouseRightButtonDown" MouseRightButtonUp="LayoutRoot_MouseRightButtonUp"</code></li>
<li>In the codebehind:</li>
</ol>
<pre class="brush: csharp">
using System.Windows.Controls;

...

private void LayoutRoot_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
    e.Handled = true;
}

private void LayoutRoot_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
    var contextMenu = new ContextMenu();

    var menuItem = new MenuItem();
    menuItem.Header = "First menu item";
    menuItem.Click += menuItem_Click;
    contextMenu.Items.Add(menuItem);

    contextMenu.IsOpen = true;
    contextMenu.HorizontalOffset = e.GetPosition(null).X;
    contextMenu.VerticalOffset = e.GetPosition(null).Y;
}

private void menuItem_Click(object sender, System.Windows.RoutedEventArgs e)
{
    System.Windows.MessageBox.Show("First menu item was clicked");
}
</pre>
<h3>Notes</h3>
<ul>
<li>If you don&#8217;t include a reference to <code>System.Windows.Controls</code>, you won&#8217;t be able to compile, with the error &#8220;&#8216;System.Windows.Controls.MenuItem&#8217; does not contain a definition for &#8216;Header&#8217; and no extension method &#8216;Header&#8217; accepting a first argument of type &#8216;System.Windows.Controls.MenuItem&#8217; could be found (are you missing a using directive or an assembly reference?)&#8221;</li>
<li>Ensure that <code>System.Windows.Controls.Toolkit</code> (if present) is version 4.0.5.0. If it&#8217;s version 2.0.5.0, you&#8217;ll get runtime error &#8220;Unknown parser error: Scanner 2148474880. [Line: 818 Position: 596]&#8221;</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.rizalalmashoor.com/blog/implementing-the-right-click-context-menu-in-silverlight-4/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Mastering Agile Management using Scrum</title>
		<link>http://www.rizalalmashoor.com/blog/mastering-agile-management-using-scrum/</link>
		<comments>http://www.rizalalmashoor.com/blog/mastering-agile-management-using-scrum/#comments</comments>
		<pubDate>Wed, 10 Nov 2010 16:15:31 +0000</pubDate>
		<dc:creator>Rizal Almashoor</dc:creator>
		
		<category><![CDATA[Agile]]></category>

		<category><![CDATA[Project management]]></category>

		<guid isPermaLink="false">http://www.rizalalmashoor.com/blog/mastering-agile-management-using-scrum/</guid>
		<description><![CDATA[This week I attended a workshop on Mastering Agile Management using Scrum. The trainer was Jesse Fewell (rhymes with &#8220;jewel&#8221;) from RippleRock.
First, the verdict. This training course is about concepts; it can easily become academic and lofty-sounding if the trainer simply goes through the slides and recites his lecture notes. The teacher will need to [...]]]></description>
			<content:encoded><![CDATA[<p>This week I attended a workshop on Mastering Agile Management using Scrum. The trainer was <a href="http://www.jessefewell.com">Jesse Fewell</a> (rhymes with &#8220;jewel&#8221;) from <a href="http://www.ripple-rock.com">RippleRock</a>.</p>
<p>First, the verdict. This training course is about concepts; it can easily become academic and lofty-sounding if the trainer simply goes through the slides and recites his lecture notes. The teacher will need to have passion, deep industry experience, an irreverent sense of humour, and showmanship for the participants to really appreciate the subject &ndash; fortunately, Jesse has all these in spades. What I liked most was that Jesse was explicit and forthright in distinguishing between essence and decoration. Insisting on doing things The One Correct Way would be completely missing the point. Instead, based on the principles, customize the techniques to fit the project.</p>
<h3>Core principles, as I understand them</h3>
<ol>
<li>The customer is not purchasing scope; he is funding a project. Which means, focus on delivering what the customer really wants instead of what he thinks he wants.</li>
<li>Fixed schedule; fixed cost; dynamic scope.</li>
<li>Frequent, time-boxed delivery of complete features which meet the customer&#8217;s definition of done.</li>
<li>People perform best when they&#8217;re empowered to self-organize and think for themselves.</li>
<li>Not wasting the customer&#8217;s money is a moral prerogative. Treating people with respect is a moral prerogative. Letting people utilize their full potential is a moral prerogative.</li>
</ol>
<h3>From my personal notes</h3>
<ul>
<li>Agile is simple. Agile is hard.</li>
<li>We welcome scope change, but not scope creep. (Assuming fixed price and schedule.)</li>
<li>The daily stand-up is a risk management meeting, not a status meeting.</li>
<li>The backlog is measured by the burndown.</li>
<li>The burndown can tell the truth and force the decision-maker to make the hard decisions</li>
<li>An Agile team is one that is predictable.</li>
<li>The problem with most project plans is too detailed, too soon.</li>
<li>Undercommit and overdeliver for each sprint (especially for the first sprint).</li>
<li>Look out for wasteful gold-plating that the product owner might not even appreciate.</li>
<li>Agile estimation: separate effort from complexity and uncertainty.</li>
<li>There is no such thing as a &#8220;technical user story&#8221;, e.g., &#8220;As an architect, I &#8230;&#8221; A user story can only be signed off by the product owner. So instead of developing layer by layer (DAL, BLL, UI), deliver small vertical slices. Instead of creating all the DB tables up front, create just the tables for one user story at a time.</li>
<li>Three answers for all questions that will occur:
<ul>
<li>&#8220;How much ___?&#8221; (e.g., how much architecture?) &#8220;Just enough.&#8221;</li>
<li>&#8220;When do we do ___?&#8221; &#8220;Just in time.&#8221;</li>
<li>&#8220;Why do we have to do this?&#8221; &#8220;Just because.&#8221; (This is when meaningless but mandatory things are required to be done by external parties).</li>
</ul>
</li>
<li>Earn respect for your boundaries (i.e., to say no to requests that will overload the team) by consistently delivering on commitments for every iteration.</li>
<li>Good ScrumMasters can lead two or three teams. Great ScrumMasters lead one team.</li>
<li>Agile is about people. It will be messy. It&#8217;s a continuous journey, and it&#8217;s about &#8220;can we do better?&#8221;</li>
</ul>
<h3>Highlights from the slides</h3>
<ul>
<li>Essence: deliver early and often; inspect and adapt along the way</li>
<li>Product Owner:
<ul>
<li>&#8220;The Decider&#8221;</li>
<li>Responsible for &#8220;what we are delivering&#8221;</li>
<li>Defines what work needs to be done</li>
<li>Prioritizes which work gets done first</li>
<li>Validates whether work meets expectations</li>
</ul>
</li>
<li>ScrumMaster:
<ul>
<li>&#8220;The Catalyst&#8221;</li>
<li>Responsible for &#8220;Are we getting better?&#8221;</li>
<li>Servant Leader; teaches and corrects, but does NOT manage</li>
<li>ScrumMaster&#8217;s checklist:
<ul>
<li>How is my Product Owner doing?</li>
<li>How is my Team doing?</li>
<li>How are our Engineering Practices?</li>
<li>How is the organization doing?</li>
</ul>
</li>
</ul>
</li>
<li>Product Backlog
<ul>
<li>Integrated (in a single repository)</li>
<li>Prioritized</li>
<li>Sufficient</li>
<li>High-level</li>
<li>Often-changing</li>
</ul>
</li>
<li>Without a clear definition of &#8220;done&#8221;, all estimates fail</li>
<li>
        User story sizing:</p>
<table border="1" cellpadding="4" style="border-collapse: collapse">
<tr>
<th>Value</th>
<th>Meaning</th>
</tr>
<tr>
<td style="text-align: right">0</td>
<td>No effort</td>
</tr>
<tr>
<td style="text-align: right">1</td>
<td>No problem. We could do this in a day.</td>
</tr>
<tr>
<td style="text-align: right">2</td>
<td>&nbsp;</td>
</tr>
<tr>
<td style="text-align: right">3</td>
<td>&nbsp;</td>
</tr>
<tr>
<td style="text-align: right">5</td>
<td>Most common size</td>
</tr>
<tr>
<td style="text-align: right">8</td>
<td>&nbsp;</td>
</tr>
<tr>
<td style="text-align: right">13</td>
<td>&nbsp;</td>
</tr>
<tr>
<td style="text-align: right">20</td>
<td>&nbsp;</td>
</tr>
<tr>
<td style="text-align: right">40</td>
<td>&nbsp;</td>
</tr>
<tr>
<td style="text-align: right">100</td>
<td>Impossibly large</td>
</tr>
<tr>
<td style="text-align: right">?&nbsp;</td>
<td>Need more information</td>
</tr>
</table>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.rizalalmashoor.com/blog/mastering-agile-management-using-scrum/feed/</wfw:commentRss>
		</item>
		<item>
		<title>LINQ to Entities: Deferred Execution and Lazy Loading</title>
		<link>http://www.rizalalmashoor.com/blog/linq-to-entities-deferred-execution-and-lazy-loading/</link>
		<comments>http://www.rizalalmashoor.com/blog/linq-to-entities-deferred-execution-and-lazy-loading/#comments</comments>
		<pubDate>Mon, 08 Nov 2010 17:54:48 +0000</pubDate>
		<dc:creator>Rizal Almashoor</dc:creator>
		
		<category><![CDATA[LINQ]]></category>

		<category><![CDATA[Entity Framework]]></category>

		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://www.rizalalmashoor.com/blog/linq-to-entities-deferred-execution-and-lazy-loading/</guid>
		<description><![CDATA[How do deferred execution and lazy loading work in LINQ to Entities (Entity Framework)? Let&#8217;s find out!
First, some sample data. We don&#8217;t want to make it too simple, so let&#8217;s have three entities:

Employee, who belongs to a Department
Department, which is under a Functional Group
Functional Group

The data:
Functional Groups



Id
Description


1
Functional Group 01


2
Functional Group 02



Departments



Id
Description
FunctionalGroupId


1
Department 01
1


2
Department 02
2


3
Department 03
2



Employees



Id
First Name
Last [...]]]></description>
			<content:encoded><![CDATA[<p>How do deferred execution and lazy loading work in LINQ to Entities (Entity Framework)? Let&#8217;s find out!</p>
<p>First, some sample data. We don&#8217;t want to make it too simple, so let&#8217;s have three entities:</p>
<ol>
<li>Employee, who belongs to a Department</li>
<li>Department, which is under a Functional Group</li>
<li>Functional Group</li>
</ol>
<p>The data:</p>
<h3>Functional Groups</h3>
<p></p>
<table border="1" cellpadding="4" style="border: 1px solid black; border-collapse: collapse">
<tr>
<th>Id</th>
<th>Description</th>
</tr>
<tr>
<td>1</td>
<td>Functional Group 01</td>
</tr>
<tr>
<td>2</td>
<td>Functional Group 02</td>
</tr>
</table>
<p></p>
<h3>Departments</h3>
<p></p>
<table border="1" cellpadding="4" style="border: 1px solid black; border-collapse: collapse">
<tr>
<th>Id</th>
<th>Description</th>
<th>FunctionalGroupId</th>
</tr>
<tr>
<td>1</td>
<td>Department 01</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>Department 02</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>Department 03</td>
<td>2</td>
</tr>
</table>
<p></p>
<h3>Employees</h3>
<p></p>
<table border="1" cellpadding="4" style="border: 1px solid black; border-collapse: collapse">
<tr>
<th>Id</th>
<th>First Name</th>
<th>Last Name</th>
<th>DepartmentId</th>
</tr>
<tr>
<td>1</td>
<td>Employee</td>
<td>One</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>Employee</td>
<td>Two</td>
<td>1</td>
</tr>
<tr>
<td>3</td>
<td>Employee</td>
<td>Three</td>
<td>2</td>
</tr>
<tr>
<td>4</td>
<td>Employee</td>
<td>Four</td>
<td>2</td>
</tr>
<tr>
<td>5</td>
<td>Employee</td>
<td>Five</td>
<td>3</td>
</tr>
</table>
<h2>Experiment #1: Lazy loading and deferred execution</h2>
<pre class="brush: csharp">
var context = new SampleModel();

var employees = context.Employees;

foreach (var employee in employees)
{
    Console.WriteLine(&quot;{0} {1}&quot;,
        employee.FirstName,
        employee.LastName);
}
Console.ReadLine();
</pre>
<h3>Results</h3>
<p><code>Employee One<br />
Employee Two<br />
Employee Three<br />
Employee Four<br />
Employee Five<br /></code></p>
<h3>Generated SQL Statements</h3>
<p>I placed a breakpoint right before the foreach loop. Before foreach: nothing. After foreach:</p>
<p><code>SELECT<br />
[Extent1].[Id] AS [Id],<br />
[Extent1].[FirstName] AS [FirstName],<br />
[Extent1].[LastName] AS [LastName],<br />
[Extent1].[DepartmentId] AS [DepartmentId]<br />
FROM [dbo].[Employees] AS [Extent1]</code></p>
<p>Which means that execution is deferred until properties are hit (.FirstName and .LastName). Also, the Departments and FunctionalGroups tables aren&#8217;t loaded, because of lazy loading.</p>
<h2>Experiment #2: Deferred execution</h2>
<pre class="brush: csharp">
var context = new SampleModel();

var employees = context.Employees;

foreach (var employee in employees)
{
    Console.WriteLine(&quot;{0} {1} - {2} - {3}&quot;,
        employee.FirstName,
        employee.LastName,
        employee.Department.Description,
        employee.Department.FunctionalGroup.Description);
}
Console.ReadLine();
</pre>
<h3>Results</h3>
<p><code>Employee One - Department 01 - Functional Group 01<br />
Employee Two - Department 01 - Functional Group 01<br />
Employee Three - Department 02 - Functional Group 02<br />
Employee Four - Department 02 - Functional Group 02<br />
Employee Five - Department 03 - Functional Group 02<br /></code></p>
<h3>Generated SQL Statements</h3>
<p>Before foreach: nothing. After foreach:</p>
<p><code>SELECT<br />
[Extent1].[Id] AS [Id],<br />
[Extent1].[FirstName] AS [FirstName],<br />
[Extent1].[LastName] AS [LastName],<br />
[Extent1].[DepartmentId] AS [DepartmentId]<br />
FROM [dbo].[Employees] AS [Extent1]</p>
<p>exec sp_executesql N&#8217;SELECT<br />
[Extent1].[Id] AS [Id],<br />
[Extent1].[Description] AS [Description],<br />
[Extent1].[FunctionalGroupId] AS [FunctionalGroupId]<br />
FROM [dbo].[Departments] AS [Extent1]<br />
WHERE [Extent1].[Id] = @EntityKeyValue1&#8242;,N&#8217;@EntityKeyValue1 int&#8217;,@EntityKeyValue1=1</p>
<p>exec sp_executesql N&#8217;SELECT<br />
[Extent1].[Id] AS [Id],<br />
[Extent1].[Description] AS [Description]<br />
FROM [dbo].[FunctionalGroups] AS [Extent1]<br />
WHERE [Extent1].[Id] = @EntityKeyValue1&#8242;,N&#8217;@EntityKeyValue1 int&#8217;,@EntityKeyValue1=1</p>
<p>exec sp_executesql N&#8217;SELECT<br />
[Extent1].[Id] AS [Id],<br />
[Extent1].[Description] AS [Description],<br />
[Extent1].[FunctionalGroupId] AS [FunctionalGroupId]<br />
FROM [dbo].[Departments] AS [Extent1]<br />
WHERE [Extent1].[Id] = @EntityKeyValue1&#8242;,N&#8217;@EntityKeyValue1 int&#8217;,@EntityKeyValue1=2</p>
<p>exec sp_executesql N&#8217;SELECT<br />
[Extent1].[Id] AS [Id],<br />
[Extent1].[Description] AS [Description]<br />
FROM [dbo].[FunctionalGroups] AS [Extent1]<br />
WHERE [Extent1].[Id] = @EntityKeyValue1&#8242;,N&#8217;@EntityKeyValue1 int&#8217;,@EntityKeyValue1=2</p>
<p>exec sp_executesql N&#8217;SELECT<br />
[Extent1].[Id] AS [Id],<br />
[Extent1].[Description] AS [Description],<br />
[Extent1].[FunctionalGroupId] AS [FunctionalGroupId]<br />
FROM [dbo].[Departments] AS [Extent1]<br />
WHERE [Extent1].[Id] = @EntityKeyValue1&#8242;,N&#8217;@EntityKeyValue1 int&#8217;,@EntityKeyValue1=3</code></p>
<p>Again, query execution is deferred. This time, the Departments and FunctionalGroups tables are loaded, because I hit both .Department.Description and .Department.FunctionalGroup.Description.</p>
<p>Notice that lots of small SQL statements are sent to the DB to fetch data one piece at a time.</p>
<h2>Experiment #3: Adding a using statement</h2>
<pre class="brush: csharp">
IEnumerable&lt;Employee&gt; employees = null;

using (var context = new SampleModel())
{
    employees = context.Employees;
}

foreach (var employee in employees)
{
    Console.WriteLine(&quot;{0} {1} - {2} - {3}&quot;,
        employee.FirstName,
        employee.LastName,
        employee.Department.Description,
        employee.Department.FunctionalGroup.Description);
}

Console.ReadLine();
</pre>
<h3>Results</h3>
<p>We get an exception! <em>The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.</em> Execution has been deferred, but at the point where the execution is supposed to happen, there is no longer any data context.</p>
<p>The solution is to use either ToArray() or ToList() to not defer execution.</p>
<h2>Experiment #4: Immediate execution using ToArray()</h2>
<pre class="brush: csharp">
IEnumerable&lt;Employee&gt; employees = null;

using (var context = new SampleModel())
{
    employees = context.Employees.ToArray();
}

foreach (var employee in employees)
{
    Console.WriteLine(&quot;{0} {1} - {2} - {3}&quot;,
        employee.FirstName,
        employee.LastName,
        employee.Department.Description,
        employee.Department.FunctionalGroup.Description);
}

Console.ReadLine();
</pre>
<h3>Generated SQL Statements</h3>
<p>Before the foreach loop:</p>
<p><code>SELECT<br />
[Extent1].[Id] AS [Id],<br />
[Extent1].[FirstName] AS [FirstName],<br />
[Extent1].[LastName] AS [LastName],<br />
[Extent1].[DepartmentId] AS [DepartmentId]<br />
FROM [dbo].[Employees] AS [Extent1]</code></p>
<p>After the foreach loop:</p>
<p>An exception, again! <em>The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.</em> Because of lazy loading, the Departments and FunctionalGroups tables weren&#8217;t loaded at the outset. So when .Department.Description and .Department.FunctionalGroup.Description were hit, there was a run-time error due to entities not being able to be loaded.</p>
<p>(Note: this implies that ToArray() or ToList(), on their own, will result in immediate execution only for the entity in question. Related entities might be loaded down the line if the relevant properties are hit.)</p>
<p>The solution is to use Include.</p>
<h2>Experiment #5: Immediate execution plus eager loading</h2>
<pre class="brush: csharp">
IEnumerable&lt;Employee&gt; employees = null;

using (var context = new SampleModel())
{
    employees = context.Employees
        .Include(&quot;Department.FunctionalGroup&quot;)
        .ToArray();
}

foreach (var employee in employees)
{
    Console.WriteLine(&quot;{0} {1} - {2} - {3}&quot;,
        employee.FirstName,
        employee.LastName,
        employee.Department.Description,
        employee.Department.FunctionalGroup.Description);
}

Console.ReadLine();
</pre>
<h3>Results</h3>
<p><code>Employee One - Department 01 - Functional Group 01<br />
Employee Two - Department 01 - Functional Group 01<br />
Employee Three - Department 02 - Functional Group 02<br />
Employee Four - Department 02 - Functional Group 02<br />
Employee Five - Department 03 - Functional Group 02<br /></code></p>
<h3>Generated SQL Statements</h3>
<p>Before the foreach loop:</p>
<p><code>SELECT<br />
[Extent1].[Id] AS [Id],<br />
[Extent1].[FirstName] AS [FirstName],<br />
[Extent1].[LastName] AS [LastName],<br />
[Extent1].[DepartmentId] AS [DepartmentId],<br />
[Extent2].[Id] AS [Id1],<br />
[Extent2].[Description] AS [Description],<br />
[Extent2].[FunctionalGroupId] AS [FunctionalGroupId],<br />
[Extent3].[Id] AS [Id2],<br />
[Extent3].[Description] AS [Description1]<br />
FROM   [dbo].[Employees] AS [Extent1]<br />
LEFT OUTER JOIN [dbo].[Departments] AS [Extent2] ON [Extent1].[DepartmentId] = [Extent2].[Id]<br />
LEFT OUTER JOIN [dbo].[FunctionalGroups] AS [Extent3] ON [Extent2].[FunctionalGroupId] = [Extent3].[Id]</code></p>
<p>After the foreach loop: nothing.</p>
<p>Hats off to the Entity Framework for being clever enough to use left joins for many-to-one relationships.</p>
<h2>Experiment #6: Immediate execution, no lazy loading</h2>
<p>Let&#8217;s say we don&#8217;t want FunctionalGroups to be loaded if the .Department.FunctionalGroup property is hit somewhere down the line. We only want Departments to be loaded.</p>
<pre class="brush: csharp">
IEnumerable&lt;Employee&gt; employees = null;

using (var context = new SampleModel())
{
    employees = context.Employees
        .Include(&quot;Department&quot;)
        .ToArray()
        .Select(x => new Employee
        {
            FirstName = x.FirstName,
            LastName = x.LastName,
            Department = new Department
            {
                Description = x.Department.Description
            }
        });
}

foreach (var employee in employees)
{
    Console.WriteLine("{0} {1} - {2} - {3}",
        employee.FirstName,
        employee.LastName,
        employee.Department != null ? employee.Department.Description : string.Empty,
        employee.Department != null &#038;&#038; employee.Department.FunctionalGroup != null ? employee.Department.FunctionalGroup.Description : string.Empty);
}

Console.ReadLine();
</pre>
<h3>Results</h3>
<p><code>Employee One - Department 01 -<br />
Employee Two - Department 01 -<br />
Employee Three - Department 02 -<br />
Employee Four - Department 02 -<br />
Employee Five - Department 03 -<br /></code></p>
<h3>Generated SQL Statements</h3>
<p>Before the foreach loop:</p>
<p><code>SELECT<br />
[Extent1].[Id] AS [Id],<br />
[Extent1].[FirstName] AS [FirstName],<br />
[Extent1].[LastName] AS [LastName],<br />
[Extent1].[DepartmentId] AS [DepartmentId],<br />
[Extent2].[Id] AS [Id1],<br />
[Extent2].[Description] AS [Description],<br />
[Extent2].[FunctionalGroupId] AS [FunctionalGroupId]<br />
FROM  [dbo].[Employees] AS [Extent1]<br />
LEFT OUTER JOIN [dbo].[Departments] AS [Extent2] ON [Extent1].[DepartmentId] = [Extent2].[Id]</code></p>
<p>After the foreach loop: nothing. FunctionalGroups isn&#8217;t loaded even when .Department.FunctionalGroup is hit, because we&#8217;re returning new instances of the Employee entity, not the ObjectContext-derived instances.</p>
<h2>Conclusion</h2>
<p>Deferred execution and lazy loading are two related concepts in LINQ to Entities. By default, execution is performed only when properties are hit, so that only the necessary entities are loaded. However, this might be undesirable as multitudes of small queries are generated and sent to the server at run-time. If the entities that need to be loaded are known at compile-time by the programmer, it might be better to not use deferred execution nor lazy loading, and ensure that the optimal SQL query is generated and sent to the server by using the techniques highlighted above.</p>
<h2>Note of Thanks</h2>
<p>I would like to extend my deepest appreciation to Nick Zhebrun and Yuri Korolev for their <a href="http://anjlab.com/en/projects/opensource/sqlprofiler">AnjLab Sql Express Profiler</a>. Truly useful.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rizalalmashoor.com/blog/linq-to-entities-deferred-execution-and-lazy-loading/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>

