Click here to Skip to main content
Click here to Skip to main content
Go to top

Connection Scope for the Entity Framework

, 6 Apr 2010
Rate this:
Please Sign up or sign in to vote.
A Connection Scope for the Entity Framework that allows to execute commands in a single connection
Attention: This code is for VS 2010 and EF v4.

Introduction

This code gives you the possibility to group entity framework database operations in the business layer so that they will be executed in one single open connection, even if they are separated commands in the backend layer.  

Background

If you use the TransactionScope class, then there will still be different connections (or at least the same, but opened and closed several times), but they will run in a distributed transaction. I wanted for e.g. an importer application, that my import runs in one open connection for performance issues.

Using the Code

There are two interesting classes: EntityConnectionScope and EntityConnectionScopeHelper. The EntityConnectionScope is the one you use in your business logic. On creation, it creates a variable in the thread store to store itself there.

public EntityConnectionScope()
{
	LocalDataStoreSlot slot = Thread.GetNamedDataSlot(Key);
	Thread.SetData(slot, this);
}

With the property Current, you can retrieve the current scope.

/// <summary>
/// Gets a reference to the EntityConnectionScope object for the current thread.
/// </summary>
public static EntityConnectionScope Current
{
	get
	{
		EntityConnectionScope scope = null;

		LocalDataStoreSlot slot = Thread.GetNamedDataSlot(Key);
		scope = Thread.GetData(slot) as EntityConnectionScope;

		return scope;
	}
}

The next interesting part is the property EntityConnection. At the first call, it initializes an entity connection and opens it. Because I don't know the name of the connection string, I made a new tag in the app.config file named EFConnectionStringName, that holds the connection tag name.

public EntityConnection EntityConnection
{
	get
	{
		if (entityConnection == null)
		{
			entityConnection = new EntityConnection
				(Configuration.EFConnectionStringName);
		}

		if (entityConnection.State == ConnectionState.Closed)
		{
			entityConnection.Open();
		}

		return entityConnection;
	}
}

The class implements IDisposable. Without that, you can't use the using keyword. It ensures that after the usage of the EntityConnectionScope, the connection is closed and released, even in case of exceptions.

public void Dispose()
{
	if (entityConnection != null)
	{
		entityConnection.Close();
		entityConnection.Dispose();
	}

	Thread.FreeNamedDataSlot(Key);
}

The helper class is used in the backend. There you check if a ConnectionScope is active. If yes, take its connection (that is open) and pass it to the ObjectContext. If not, create a new connection (don't open it) and pass this to the ObjectContext.

/// <summary>
/// If we are in a ConnectionScope we return that 
/// (open) connection, otherwise a new closed one
/// </summary>
/// <returns>EnityConnection</returns>
internal static EntityConnection GetEntityConnection()
{
	if (EntityConnectionScope.Current != null)
	{
		return EntityConnectionScope.Current.EntityConnection;
	}
	else
	{
		return new EntityConnection(Configuration.EFConnectionStringName);
	}
}

The ObjectContext (this is where the EntityFramework magic happens) is clever enough, that an open connection is not closed at the end. On the other hand if it gets a closed connection, it closes it at the end.

using (ModelContainer proxy = 
	new ModelContainer(EntityConnectionScopeHelper.GetEntityConnection()))
{
	return proxy.Customers.Include("Orders").SingleOrDefault(c => c.Id == id);
}

The usage of the EntityScope is quite simple, like:

using (EntityConnectionScope scope = new EntityConnectionScope())
{
	//call backend methods here
}  

In my small sample, I have a simple data model. Customer : Order = 1 : n. I create a customer, then an order and in the end retrieve that customer from the backend. As you can see in the profiler, it opens and closes the connection three times (first red rectangle). When doing the same in the EntityConnectionScope, the connection is held open for all three commands (second red rectangle).

History

  • V 1.0 2010/04/06 Initial version 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Rainer Halanek
Software Developer (Senior)
Austria Austria
Born and living in Vienna, Austria. Started with Pascal in 1993 and MS-DOS 5.0. After that a little C++ in OS/2 and loads of VBA with Access in Windows 95,98, NT. To get more professionel I started C# in 2002 and did some MCP exams on that. After working for my own company I got hired by different companies. Currently I'm employed at the Federal Chambers of Commerce as a Senior Software Engineer.

Comments and Discussions

 
Generalabout wcf Pinmemberdonnng8-Oct-13 23:21 
QuestionTransaction Scope in v2? PinmemberFree_Moe5-Jun-12 13:47 
GeneralThreadStatic PinmemberPaulo Zemek7-Apr-10 7:24 
In MSDN it says that ThreadStatic variables are better than Thread Data-Slots.
 
After all, they are faster and no one else will have the chance to use the same name.
GeneralRe: ThreadStatic PinmemberRainer Halanek7-Apr-10 7:27 
QuestionBehaviour in a multi-threaded application [modified] Pinmemberdaws@mtbsoft.com.au6-Apr-10 15:27 
AnswerRe: Behaviour in a multi-threaded application PinmemberRainer Halanek6-Apr-10 20:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140926.1 | Last Updated 7 Apr 2010
Article Copyright 2010 by Rainer Halanek
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid