One DataContext For Linq To SQL While Using Repository Pattern - c#

I am fairly new to .NET C# development and recently started using LINQ to SQL for the majority of my data access layer. Unfortunately, I have been struggling with how to manage my DataContext so that I don't get the dreaded exceptions that result from entities either not being attached to a context or attempting to attach an entity to one context while it is attached to another. After much reading, I believe that the best solution for my application is to leave the DataContext open for the entire duration of my application.
In short, I am using the Repository pattern to implement the basic CRUD operations (i.e. Create, Read, Update, and Destroy) for all entities managed by my context. My implementation of the Repository is included below. In addition to the Repository, I have DAOs (Data Access Objects) for each entity that has more specific data access methods (i.e. CustomerDAO.getCustomerByName(string name), etc...). Each of my Windows forms has its' own instance of one or more DAOs (that extend Repository) and the DataContext in my repository is static. The problem that I am running into is that even though my DataContext in the repository class below is declared as static, I'm finding that each distinct DAO actually gets a different instance of the DataContext. For example, if I have 8 references to the CustomerDAO, they all have the same DataContext. But, if I create one WorkOrderDAO I get another instance of the DataContext and all future instances of WorkOrderDAO get this same DataContext. More specifically, I discovered this in the following scenario.
1) Use an instance of WorkOrderDAO to load all WorkOrders into ListView - Has one DataContext
2) Use an instance of WorkOrderJobsDAO to attempt to delete one of the jobs on the WorkOrder. This is a collection on the WorkOrder. Has a different DataContext so I can't attach
Is this a problem with how I have implemented the Repository below? The only thing that I can think of to solve this issue is to create a Singleton that the Repository uses to get its' DataContext. Can anyone make any recommendations here for how I should manage the Context?
public class Repository<T> : IRepository<T>
where T : class
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
protected static DomainClassesDataContext db = new DomainClassesDataContext();
private static bool dataContextOptionsInitialized = false;
public Repository()
{
if (!dataContextOptionsInitialized)
{
db.DeferredLoadingEnabled = true;
dataContextOptionsInitialized = true;
}
}
public void AddEntity(T entity)
{
GetTable.InsertOnSubmit(entity);
SaveAll();
}
public void DeleteEntity(T entity, bool attach)
{
if(attach)
GetTable.Attach(entity);
GetTable.DeleteOnSubmit(entity);
SaveAll();
}
public void UpdateEntity(T entity, bool attach)
{
if(attach)
GetTable.Attach(entity, true);
SaveAll();
}
public System.Data.Linq.Table<T> GetTable
{
get { return db.GetTable<T>(); }
}
public IEnumerable<T> All()
{
return GetTable;
}
public void SaveAll()
{
db.SubmitChanges();
}
}

Generic classes in C# gets "expanded" on compilation, so your Repository will be a different class than Repository, which is why the static variables are different instances between your DTOs. So yes you probably want to save it somewhere else, like a in a Singleton class.

Related

Which is the better, an instance variable or a local variable for an EF context?

I know that the title looks a bit bad :) But I dont know how to explain my problem..
This is typically a basic problem for me but I dont know answer..
I am writing a server application which is using eneter library for client-server communinication and also it has a DAL gets data from database. as it a server application, it always need to communicate with database, so I dont know which way is more effective. (approx, max 50 clients will be connected to server)
I am using entity framework and created a model from my mysql db.
the first code is here
private MyEntities ent;
public DbHelper()
{
ent = new MyEntities();
}
void Foo()
{
ent.Mytable.where......
....
}
and second type code is
void Foo()
{
using (MyEntities ent = new MyEntities())
{
ent.Mytable.where...
}
}
Can I use using statement or create a global instance variable for dal class and use it for each functions.. ?
Better yet, implement IDisposable on your DAL class:
public sealed class MyDal implements IDisposable
{
private MyEntities ent = new MyEntities();
void Foo()
{
ent.Mytable.where......
....
}
public void Dispose()
{
ent.Dispose();
}
}
Then...
using(var dal = new MyDal())
{
dal.Foo();
//....
}
Take a read here about why my IDisposable is sealed.
From performance viewpoint it doesn't matter. Compared to the actual database interaction creating a context instance is a very fast operation.
However, you should dispose the created context in any case because it holds a database connection as a native resource.
If your want to work with a context member in your DbHelper class this class should implement IDisposable so that you can dispose the context when the DbHelper instance itself gets disposed:
public class DbHelper : IDisposable
{
private MyEntities ent;
public DbHelper()
{
ent = new MyEntities();
}
public void Foo()
{
//...
}
public void Bar()
{
//...
}
public void Dispose() // implementation of IDisposable
{
ent.Dispose();
}
}
You could use this class in a using block then:
using (var helper = new DbHelper())
{
helper.Foo();
helper.Bar();
} // helper and helper.ent gets disposed now
This depends on what other methods exist and what they do. If you want to make changes and persist those changes using the ORM, you will need the data-context that created the objects. Also, if you want the identity manager to give you the same object instance if you query the same thing twice, you will need to use the same data-context - so you'll need to keep it handy. Finally, if the type uses lazy loading and you expect it to work - then that won't work if you have disposed the data-context.
If, however, you just want read-only access to the data without change tracking, lazy loading or identity management : dispose eagerly. And maybe consider things like micro-ORMs which simply don't have those features (deliberately, to be minimal and fast).
The 2 approaches are very different in terms of the scope of the change-tracking. If both work equally well then make sure to use WithNoTracking.
You can create a member variable for your entities like in your first code. But because you cannot write a using(){} statement around it the containing class should be IDisposable. And then the consuming class should use it inside a using(){}.

Proper use of "Using" statement for datacontext

I’m using Linq to Entities and lately, I found that a lot of folks recommending wrapping the datacontext in a using statement like this:
Using(DataContext db = new DataContext) {
var xx = db.customers;
}
This makes sense. However, I’m not sure how to incorporate this practice in my model.
For example: I have an interface (let’s call it customer) and it is implemented by a repository like this:
namespace Models
{
public class rCustomer : iCustomer
{
readonly DataContext db = new DataContext();
public customer getCustomer(Guid id)
{
return db.customers.SingleOrDefault(por => por.id == id);
}
public iQueryable<customer> getTopCustomers()
{
return db.customers.Take(10);
}
//*******************************************
//more methods using db, including add, update, delete, etc.
//*******************************************
}
}
Then, to take the advantage of using, I will need to change the methods to look like this:
namespace Models
{
public class rCustomer : iCustomer
{
public customer getCustomer(Guid id)
{
using(DataContext db = new DataContext()) {
return db.customers.SingleOrDefault(por => por.id == id);
}
}
public iQueryable<customer> getTopCustomers()
{
using(DataContext db = new DataContext()) {
return db.customers.Take(10);
}
}
//*******************************************
//more methods using db
//*******************************************
}
}
My question is: the recommendation of using “Using” is really that good? Please take in consideration that this change will be a major one, I have about 25 interfaces/repository combos, and each has about 20-25 methods, not to mention the need to re-test everything after finish.
Is there other way?
Thanks!
Edgar.
You can implement a Database factory which will cause your DbContext is being reused.
You can achieve this as follows:
DatabaseFactory class:
public class DatabaseFactory : Disposable, IDatabaseFactory
{
private YourEntities _dataContext;
public YourEntities Get()
{
return _dataContext ?? (_dataContext = new YourEntities());
}
protected override void DisposeCore()
{
if (_dataContext != null)
_dataContext.Dispose();
}
}
Excerpt of the Repository base class:
public abstract class Repository<T> : IRepository<T> where T : class
{
private YourEntities _dataContext;
private readonly IDbSet<T> _dbset;
protected Repository(IDatabaseFactory databaseFactory)
{
DatabaseFactory = databaseFactory;
_dbset = DataContext.Set<T>();
}
protected IDatabaseFactory DatabaseFactory
{
get;
private set;
}
protected YourEntities DataContext
{
get { return _dataContext ?? (_dataContext = DatabaseFactory.Get()); }
}
Your table's repository class:
public class ApplicationRepository : Repository<YourTable>, IYourTableRepository
{
private YourEntities _dataContext;
protected new IDatabaseFactory DatabaseFactory
{
get;
private set;
}
public YourTableRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
DatabaseFactory = databaseFactory;
}
protected new YourEntities DataContext
{
get { return _dataContext ?? (_dataContext = DatabaseFactory.Get()); }
}
}
public interface IYourTableRepository : IRepository<YourTable>
{
}
}
This works perfectly together with AutoFac constructor injection as well.
Considering the code provided I see, you esplicitly use readonly DataContext db = new DataContext(); like a global variable, so you consider to have that object lifetime along with your rCustomer class instance lifetime.
If this is true, what you can do, instead of rewriting everything, you can implement IDisposable and inside Dispose() code something like
private void Dispose()
{
if(db != null)
db.Dispose();
}
Hope this helps.
As others have mentioned, it's important for the data contexts to be disposed. I won't go into that further.
I see three possible designs for the class that ensure that the contexts are disposed:
The second solution you provide in which you create a data context within the scope of each method of rCustomer that needs it so that each datacontext is in a using block.
Keep the data context as an instance variable and have rCustomer implement IDisposable so that when rCustomer is disposed you can dispose of it's data context. This means that all rCustomer instances will need to be wrapped in using blocks.
Pass an instance of an existing data context into rCustomer through its constructor. If you do this then rCustomer won't be responsible for disposing of it, the user of the class will. This would allow you to use a single data context across several instances of rCustomer, or with several different classes that need access to the data context. This has advantages (less overhead involved in creating new data contexts) and disadvantages (larger memory footprint as data contexts tend to hold onto quite a lot of memory through caches and the like).
I honestly think option #1 is a pretty good one, as long as you don't notice it performing too slowly (I'd time/profile it if you think it's causing problems). Due to connection pooling it shouldn't be all that bad. If it is, I'd go with #3 as my next choice. #2 isn't that far behind, but it would likely be a bit awkward and unexpected for other members of your team (if any).
The DataContext class is wrapped in a Using statement because it implements the IDisposable interface.
Internal to the DataContext it is using SqlConnection objects and SqlCommand objects. In order to correctly release these connection back to the Sql Connection Pool, they need to be disposed of.
The garbage collector will eventually do this, but it will take two passes due to the way IDisposable objects are managed.
It's strongly encouraged that Dispose is called and the Using statement is a nice way to do this.
Read these links for more indepth explanation:
http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/2625b105-2cff-45ad-ba29-abdd763f74fe/
http://www.c-sharpcorner.com/UploadFile/DipalChoksi/UnderstandingGarbageCollectioninNETFramework11292005051110AM/UnderstandingGarbageCollectioninNETFramework.aspx
An alternative would be to make your rCustomer class implement IDisposable, and then in your Dispose method, you can call Dispose on your DataContext if it is not null. However, this just pushes the Disposable pattern out of your rCustomer class, into whatever types are using rCustomer.

Class for DB access via an Entity Model, how to cleanup the connection?

I have a class I'm using to handle all my DB interaction. Basically when an instance of this class is created it creates an instance of the model, which will persist until the DataAccess object is out of scope.
public class DataAccess
{
ModelContainer model;
public DataAccess()
{
model = new ModelContainer();
}
public void Close()
{
if (model != null)
{
model.Connection.Close();
model.Dispose();
}
}
}
What cleanup do I need to preform on the model? I've cought my self forgetting to call my Close() method when writing my unit tests. I like the using(DataAccess data = new DataAccess()) way of dealing with DB objects like you use in LINQ to SQL, so should I make DataAccess implement iDisposeable?
If you have items in the class that implements IDisposable it is a good idea to make your class implement that aswell so that they get disposad properly. If you do not call them upon disposing your class you might have some unexcepted memory leaks. And it's easy to write "using" as you mentioned which you only can do when you implement IDisposable.
This is an excellent example on how to implenet IDisosable:
http://msdn.microsoft.com/en-us/library/system.idisposable.aspx

How to design an application such that it's easily testable using unit testing? [duplicate]

This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
Writing “unit testable” code?
I am new to unit testing. Today on SO I found an answer to a question about interfaces in c#. That got me thinking about best practices for building an applications that's testable by design.
I use interfaces very lightly in the main application that I work on. That's made it very difficult to test because I have no way of injecting test data into most classes as each class relies directly upon other classes, and thus the other classes implementations.
So my question is, for a C# application, how would you design your classes and implementations, and what tools would you use to ensure that methods and classes can be independently unit tested by supplying test data for each method or class.
EDIT: Specifically, if you look at the question I linked to, the answer uses this:
IWidget w = ObjectFactory.GetInstance();
I never used a class/object factory, so I'm curious how that works and how it would be implemented.
Dependency Injection is the solution you are looking for. The general problem has to do with where your dependencies are created. Normally, when writing an object-oriented program, the natural instinct is to create your dependencies directly using the new keyword at the location you need your dependencies. Sometimes you may create long-lived dependencies in a constructor.
To make your classes more unit testable, you need to "invert" that norm, and create your dependencies externally (or create a factory/provider/context that can in turn be injected and used to create instances of other dependencies), and "inject" those dependencies into your class. The two most common mechanisms of injection are either as parameters to a constructor, or with properties with setters. By externalizing dependency management in this way, you are easily able to create mocked versions of those dependencies and pass those in, allowing you to test your units of code in full isolation from the rest of your application.
To support dependency injection and make it easier to manage Inversion of Control (IoC) containers have appeared. An IoC container is a framework that allows you to configure dependency graphs independently of the classes that participate in in those graphs. Once a dependency graph is configured (usually rooted at the single key class of interest), you can easily create instances of your objects at runtime without having to worry about manually creating all of the required dependencies as well. This helps in creating very loosely coupled, flexible code that is easy to reconfigure. An example of a very good IoC container is Castle Windsor, which provides a very rich framework for wiring up classes via dependency injection.
A very simple example of Dependency Injection would be something like the following:
interface ITaskService
{
void SomeOperation();
}
interface IEntityService
{
Entity GetEntity(object key);
Entity Save(Entity entity);
}
class TaskService: ITaskService
{
public TaskService(EntityServiceFactory factory)
{
m_factory = factory;
}
private EntityServiceFactory m_factory; // Dependency
public void SomeOperation() // Method must be concurrent, so create new IEntityService each call
{
IEntityService entitySvc = m_factory.GetEntityService();
Entity entity = entitySvc.GetEntity(...);
// Do some work with entity
entitySvc.Save(entity);
}
}
class EntityServiceFactory
{
public EntityServiceFactory(RepositoryProvider provider)
{
m_provider = provider;
}
private RepositoryProvider m_provider; // Dependency
public virtual IEntityService GetEntityService()
{
var repository = m_provider.GetRepository<Entity>();
return new EntityService(repository);
}
}
class EntityService: IEntityService
{
public EntityService(IEntityRepository repository)
{
m_repository = repository;
}
private IEntityRepository m_repository; // Dependency
public Entity GetEntity(object key)
{
if (key == null) throw new ArgumentNullException("key");
// TODO: Check for cached entity here?
Entity entity = m_repository.GetByKey(key);
return entity;
}
public Entity Save(Entity entity)
{
if (entity == null) throw new ArgumentNullException(entity);
if (entity.Key == null)
{
entity = m_repository.Insert(entity);
}
else
{
m_repository.Update(entity);
}
return entity;
}
}
class RepositoryProvider
{
public virtual object GetRepository<T>()
{
if (typeof(T) == typeof(Entity))
return new EntityRepository();
else if (...)
// ... etc.
}
}
interface IEntityRepository
{
Entity GetByKey(object key);
Entity Insert(Entity entity);
void Update(Entity entity);
}
class EntityRepository: IEntityRepository
{
public Entity GetByKey(object key)
{
// TODO: Load up an entity from a database here
}
public Entity Insert(Entity entity)
{
// TODO: Insert entity into database here
}
public void Update(Entity entity)
{
// TODO: Update existing entity in database here
}
}
Dependency Injection is a great principle that allows you to create tests easily by defining mock objects where needed.
Basically the idea is that you pass in any dependency to an object, it doesn't create its own objects to operate on.
use a Mock framework to supply test data
http://ayende.com/projects/rhino-mocks.aspx
http://code.google.com/p/moq/

Testing Data Model in project that uses NHibernate for persistence

I'm still new with NHibernate, so correct me if I'm wrong on any of this.
When you are using NHibernate to build collections of objects from database records, NH takes care of instantiating your collections and populating them.
How do you instantiate your ISet collections when you are writing tests that don't actually use NH?
You can instantiate a field by using the constructor or by instantiating the field directly in the declaration. Classes mapped with NHibernate can be persistence ignorant.
public class MyEntity
{
private readonly ISet<ChildEntity> children;
public MyEntity()
{
children = new HashedSet<ChildEntity>();
}
public IEnumerable<ChildEntity> Children
{
get { return children; }
}
public void AddChild(Child child)
{
children.Add(child);
}
}
Assuming you're testing something other than the data layer itself (like your domain logic, for example), you can simply create the objects yourself and populate them with test case data. Or you could be really sneaky and create a database with all your test cases.

Categories

Resources