views:

198

answers:

2

I am a new asp.net programmer and I just asked this question which left me with a more general one.

What is/are the current best practices regarding Linq and data objects? Specifically when to; dim, new and dispose of them.

Also what about objects that get used in many different scopes on the same page e.g. a user data object. Should they be module level or created in each scope?

If someone could give me the cliff notes on the current best practices or even a link to an article which describes them I would greatly appreciate it.

A: 

Generally you want to pass data being operated on as parameters to functions and dependencies of types as constructor arguments. So for instance a linq data context is likely going to be something your type depends on to operate, and should therefore be injected in the constructor. The values you use to look up data in your context will change rapidly and be used repeatedly for the same context, and therefore would be function parameters on your type.

If it is the case however that your type is built to perform operations on multiple contexts within its lifetime, you might consider passing the context as function parameters, but this would probably indicate a design problem more than anything else.

As for instancing data contexts within function scopes of a type, there really isn't any reason to have that overhead in your functions unless the lifetime of your type is guaranteed to only last the lifetime of the function call itself. Even if that is the case right now, it might not be at some point in the future and so it is still better to design your types with that case in mind.

NickLarsen
+2  A: 

Quickie thoughts (I'm sitting in a meeting, so bad me)

For ASP.NET, the maximum lifetime of a data context is one post or postback. You can create more than that, but they will all die with the page unload. Yes, you should dispose of them explicitly; the using statement is the best way to handle that because it will automatically call dispose when the block ends:

using (NorthwindModel nw = new NorthwindModel())
{
    do stuff
}

Data that's returned from a LINQ query does not disappear with the data context, but at that point it's no longer connected to a context and changes can't be used to update the database any more. (You can always create a new context, then attach as a new object, or re-query and merge changes, or whatever meets your needs.)

Be very aware that a LINQ query doesn't execute until it needs to evaluate the data. It's a very easy mistake to hold onto a query while the data context gets disposed, then when the query needs to run, it can't, because it was created with a data context that no longer exists. There are two general ways to cope with this.

  1. Process the query results inside the using block for the data context.
  2. Force the query to execute, usually with .ToList() or some other method that will generate a collection of data:

    List myCustomers = (from c in nw.Customers select c).ToList();

This runs the query, copies the data into an enumerable collection, and gives you a collection that can be returned to a method caller. However, these objects are now separate from the context, so they can't be used for updates.

If you're doing CRUD with LINQ, it's a good idea to use one data context for all updates, deletes, and inserts, then call SubmitChanges() once for all the changes. This ensures that they run as a single transaction. (The data context will generate a transaction for each SubmitChanges call, if there isn't a transaction already running.)

If you want to select one item in a query, use FirstOrDefault() rather than First(). First() will throw and exception if nothing meets the selection criteria, while FirstOrDefault() will return a null. Very useful to know.

Beyond that, have fun and try lots of stuff. LINQ will change the way you think about data.

Cylon Cat