Вопрос

I have refactored some querys on linq in order to have two calls:

public IQueryable<Entity> GetAll()
{
   return context.Set<ENTITY>().Project().To<Entity>();
}

That is called from:

public int FindLastID()
{
    using(var context = new DBContext())
    {
       return GetAll().Max(p => p.id);
    }
}

The problem is that GetAll should be independently used, and it has no context. If the using context in wirtten on the GetAll method it is disposed and the Max function generates an excetion.

Is any way of calling the GetAll with no exception?

Это было полезно?

Решение

Usually all repository methods assume that a context is created. This is the most convenient way. So your FindLastID method also shouldn't create the context, unless it's a service layer method. One simple example is to use a static variable:

public void AServiceMethod()
{
    using (var context = contextProvider.CreateContext())
    {
        // call some domain operations, which use repositories

        // commit 
    }
}

Where CreateContext will open a DB session and store it in some static variable accessible from all repositories. This is not very elegant, but often is sufficient. To make it better you can use IoC as suggested by Sergey Berezovskiy. Also you may be interested in this article, recommended by Sam Leach in his answer.

Alternatively you could try something like this:

public IQueryable<Entity> GetAll()
{
    return GetAll(null);
}

public IQueryable<Entity> GetAll(DBContext context)
{
    if (context == null)
    {
        using (context = new DBContext())
        {
            return GetAll(context);
        }
    }

    return context.Set<ENTITY>().Project().To<Entity>();
}

But I'd recommend the first approach, as it's simpler and easier to maintain, comprehend.

Другие советы

This question is about Entity Framework Context Management.

See this MSDN article, Working with DbContext

It gives some general guidelines that you might find useful while thinking about refactoring and designing your data access.

When working with long-running context consider the following:

As you load more objects and their references into memory, the memory consumption of the context may increase rapidly. This may cause performance issues.

Remember to dispose of the context when it is no longer required.

If an exception causes the context to be in an unrecoverable state, the whole application may terminate.

The chances of running into concurrency-related issues increase as the gap between the time when the data is queried and updated grows.

When working with Web applications, use a context instance per request.

When working with Windows Presentation Foundation (WPF) or Windows Forms, use a context instance per form. This lets you use change-tracking functionality that context provides.

Using an IoC framework to manage the lifetime of your context is probabably the best approach as Sergey Berezovskiy said.

Also, see this old (but good) article about context lifetime management.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top