Scott Hanselman

Getting LINQ to SQL and LINQ to Entities to use NOLOCK

March 17, 2008 Comment on this post [23] Posted in LINQ
Sponsored By

I was visiting a local company where a bunch of friends work and they asked how to get LINQ to SQL to use NOLOCK. They were explicitly asking how to get the SQL generated by LINQ to SQL to add the NOLOCK hints to the end.

However, with NOLOCK (even though "everyone" has used it at some point or another) is generally considered a last resort. Queries that use NOLOCK aren't guaranteed to return correct results or technically, return any results at all.  

SQL 2005 has snapshot-based isolation levels that prevent readers from blocking writers or writers from blocking readers without allowing dirty reads.

Now, I have said that NOLOCK has served me personally very well in the past on systems of some size, but I hear what folks who say no to NOLOCK are saying. It certainly depends on one's definition of "correct results." ;)

There's three ways to get the behavior your want. Using TransactionScope is the recommended way to affect the transaction options associated with the commands generated by either LINQ to SQL or LINQ to Entities.

LINQ to SQL also supports explicitly setting the transaction on the context, so you could get the connection from the context, open it, start a transaction, and set it on the context. This can be desirable if you think SQL 2005 is promoting transactions too often, but the preferred method is TransactionScope.

ProductsNewViewData viewData = new ProductsNewViewData();
using (var t = new TransactionScope(TransactionScopeOption.Required,
    new TransactionOptions { 
IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted
})) { viewData.Suppliers = northwind.Suppliers.ToList(); viewData.Categories = northwind.Categories.ToList(); }

Here's an example where I used it in some recent code. This TransactionScope could be hidden (layered away) in your DAL (Data Access Layer) or in your Data Context directly if you wanted it to be neater.

A second way is that you can still create and call Stored Procedures (sprocs) from LINQ to SQL and those sprocs could include NOLOCK, TransactionScope is a better choice for LINQ to SQL or LINQ to Entity generated SQL if you feel that your query doesn't need to lock down the table(s) it's reading from.

Note that you'll want to be aware of which statement in your LINQ to SQL actually starts talking to the database. You can setup a query ahead of time and it won't be executed, for example, until someone calls ToList() or the like. It's at this point you'll want to wrap it in the using(TransactionScope){}.

Another third way you could set it at a DataContext level (which, to be clear, would affect every generated LINQ to SQL query executed on that context) would be to execute the command:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

...using the connection available inside your DataContext.

Thanks to David Browne and Michael Pizzo for their help on this!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

List of .NET Dependency Injection Containers (IOC)

March 13, 2008 Comment on this post [29] Posted in IOC | Learning .NET | Programming
Sponsored By

I'm trying to expand my mind around dependency injection in .NET (beyond the two frameworks I've personally used) and an starting to put together a list of .NET Dependency Injection Containers and IOC resources.

Here's what I've got so far. What am I missing?

What projects have I forgotten? Thanks!

Related Links

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

I'm Just a Caveman - The Hanselman Corollary to the Clarke/Wheeler Laws

March 13, 2008 Comment on this post [21] Posted in ASP.NET | ASP.NET MVC | DevCenter | Learning .NET | Programming
Sponsored By

cavemen-unfrozen-lawyer-web Any problem in computer science can be solved with one additional layer of indirection. But that usually will create another problem. - David Wheeler

Any sufficiently advanced technology is indistinguishable from magic. - Arthur C. Clarke.

These are two classic truisms. Recently while staring at some code trying to figure out what the heck was going on, I realized the obvious.

One additional layer of indirection is indistinguishable from magic. - Scott Hanselman, this morning in a rare moment of clarity while hopped up on Diet Coke.

In recent talk at Mix on ASP.NET MVC (there's video there also) I mentioned that a certain line of code was magic:

      public void Update(int id)
      {
         try
         {
            viewData.Product = db.Products.Single(p => p.ProductID == id);
            //MAGIC STARTS HERE
Binding.UpdateFrom(viewData.Product, Request.Form);
//END MAGIC db.SubmitChanges(); RedirectToAction("List"); } catch (InvalidOperationException err) { viewData.ErrorMessage = err.Message; RenderView("edit", viewData); } }

Why did it feel like magic? A few reasons.

  • It does a LOT. It takes all the values from a Form POST and lines them up with the public Properties in an object instance. This is done in the context of a Form POST to a Controller Action in ASP.NET MVC.
  • It isn't named well. Update is a verb, so that's cool, but the "From" makes me feel inverted.
  • The parameters are (possibly) in the wrong order. Given the name, I'd have expected UpdateFrom(Form, Product), but even then it doesn't feel write.

All of this adds up to an impedance mismatch, IMHO. It's too confusing and I'm just a caveman (video). As such, I declare it as black magic.

This magic was brought up to the team (I think I remember hitting someone, there may have been some swearing. ;) ) and Rob changed it in a number of good ways.

  • It's discoverable. He hung it off of the Request where you can actually stumble upon in.
  • It's named directly. Rather than the inverted UpdateFrom, it is now DeserializeTo which reads better left to right as in Request.DeserializeTo(product).
  • It's simpler. Because it's hanging off the object that was previously a parameter, it has one less parameter and again, reads nicely left to right.
//FEELS LESS MAGICAL 
Request.DeserializeTo(viewData.Product);

Jeff Moser's (see I told you I'd mention him twice) fine post talks about how cognitive "chunks" that represent solutions to problems can be more easily stored in our brains if they flow. Scott Bellware has called this concept "solubility." Code that uses frameworks with some balanced between focus on aesthetic and usability is more easily grokked.

I don't know if this is the final method, it's probably not, but I really enjoy discussions like this that aim to make things less like magic and more obvious and discoverable.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

The Weekly Source Code 19 - LINQ and More What, Less How

March 13, 2008 Comment on this post [19] Posted in Learning .NET | LINQ | Microsoft | Programming | Source Code
Sponsored By

Dear Reader, I present to you nineteenth in a infinite number of posts of "The Weekly Source Code."

At Mix, Clint Rutkas and I were messing around writing a plugin model for one of his apps. We were prototyping and I typed up this typical-looking plugin style code:

string[] filesToTest = Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins"), "*.dll");
foreach (string file in filesToTest)
{
    Assembly a = Assembly.LoadFrom(file);
    foreach (Type t in a.GetTypes())
    {
        if (!t.IsAbstract && t.BaseType == typeof(MyBaseClass))
        {
            myListOfInstances.Add((MyBaseClass)Activator.CreateInstance(t, credentials));
        }
    }
}

It's pretty straightforward and has little (read: no) error handling. It spins through the DLLs in the /plugins folder, loads them each (this should be more explicit rather than a blanket load of all dlls in a folder), then looks for any types that are derived from MyBaseClass that aren't abstract, then instantiates them and puts them in a list.

I'm going to quote Jeff Moser's very good blog post "What does it take to be a grandmaster" in both this post and the next one I write. It's that good. Seriously, go read it now, I'll wait here.

Jeff invokes Anders Heilsberg (Father of C# and LINQ) and:

"Anders' recent statement that future versions of C# will be about getting the programmer to declare "more of the what, and less of the how" with respect to how a result gets computed. A side effect of this is that your "chunks" tend to be more efficient for the runtime, and more importantly, your brain."

I'm going to repeat part I bolded. I like Programming Languages that allow me to declare "more of the what, and less of the how."  This how we tried to design the system at my last job and I automatically mentally migrate towards systems that encourage this kind of thinking.

So, back to the foreach loops above. My good friend (and fellow baby sign language fan) Kzu came by while Clint and I were working and suggested we turn this increasingly complex procedure into a LINQ query.

After a few tries, here's what we came up with.

myListOfInstances =
    (from file in Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins"), "*.dll")
     let a = Assembly.LoadFrom(file)
     from t in a.GetTypes()
     where !t.IsAbstract && t.BaseType == typeof(MyBaseClass) 
     select (MyBaseClass)Activator.CreateInstance(t, credentials))
    .ToList();

This is all one line, with some whitespace for readability. It says the same thing as the first chunk of code, but for some minds, it might be easier to read. This isn't a very good example of LINQ shining, from my point of view even though I like reading it. Certainly there's nowhere (I can see) for me to put error handling code that catches a bad load or bad cast in this example. There are, however, a LOT of places within that single line that one could set a breakpoint.

A better example would be like the one Jeff uses:

var primes = new int[] { 2,3,5,7,11,13,17,19,13,29,31,37,41 };
var primeSum = 0;
for (int i = 0; i < primes.Length; i++)
{
primeSum += primes[i];
}

...or even...

var primes = new int[] { 2,3,5,7,11,13,17,19,13,29,31,37,41 };
var primeSum = 0;
foreach (int i in primes)
{
  primeSum += i;
}

...could be more easily written and read like:

var primes = new int[] { 2,3,5,7,11,13,17,19,13,29,31,37,41 };
var primeSum = primes.Sum();

where .Sum() is part of LINQ as Arrays are IEnumerable.

I totally recommend you go get the free, no-installer LINQPad that comes with 200 examples from C# in a Nutshell.

Here are a few examples that I think really typify pretty code; certainly an improvement over the standard procedural code I'd usually write:

var names = new[] { "Tom", "Dick", "Harry" }.Where(n => n.Length >= 4);

Here's onen that does quite a few things to a list in a fairly clean syntax:

string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };

var results =
     (
       from n in names
       where n.Contains("a")  // Filter elements
       orderby n.Length       // Sort elements
       select n.ToUpper()     // Translate each element (project)
     ).ToList();       	

What LINQ-style queries have you written that feel more what than how?

Related, ahem, LINQS

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

ASP.NET MVC Cheesy Northwind Sample Code

March 11, 2008 Comment on this post [19] Posted in ASP.NET | ASP.NET MVC | Programming | Speaking
Sponsored By

image A number of folks wanted the code from my talk at Mix, specifically the "complete application" example with CRUD (Create, Read, Update, Delete) so here it is.

It's nothing pretty to look at, but it makes a number of points with ASP.NET MVC:

  • It uses the Default Routes to do everything.
  • It uses a ViewUserControl to avoid duplication in a Form.
  • It includes the PagedList<T> that makes Linq to SQL easier in grids.
  • It's insanely simple. There's like nothing there and it works well.
  • It uses lambdas to generate URLs like:
    • Html.ActionLink<ProductController>(c => c.Edit(p.ProductID),"Edit")
    • Which says "if someone were to call Edit with ProductID as a parameter, what would the URL look like?" The system will then use the lambda along with the already declared routes and figure out the best URL. This is very DRY and lets us change our URLs in one place and have those changes reflected everywhere.

If you want to run it you need:

I known it's cheesy to do demos with Northwind, and we're actively working on more real world, more interesting samples. That said, I'd much rather show off your code, so if you do something cool and Open Source with MVC, let me know. BTW, I've added an ASP.NET MVC category to this blog.

UPDATE #1: PhilHa updated Brad Abrams older (and much more comprehensive) Northwind code to ASP.NET MVC Preview 2, so you can download that much better code below as well.

UPDATE #2: Looks like ASP.NET MVC Preview 2 runs pretty well on Mono. Anyone want to get Northwind up over there as well?

Technorati Tags: ,,

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.