EntityFramework Контекст реализован неправильно? - PullRequest
0 голосов
/ 15 марта 2012

Сначала я работаю над кодом EF 4.2, и у меня возникает множество случайных проблем с подключением к контексту, и я удивляюсь, можно ли взглянуть на эту реализацию, а затем дать мне пощечину за неправильную работу (если это неправильно, то это)

Я разработал шаблон хранилища для этого проекта.

Я уверен, что проблема в том, как я это делаю, но в любом случае вот код:

КонтекстПровайдер

public class ContextProvider
{
    private static MyContext context;
    public static MyContext Context
    {
        get
        {
            if (context == null)
            {
                context = new MyContext();
            }

            Database.SetInitializer<MyContext>(null);

            //create the DB if it doesn't exist
            if (!context.Database.Exists())
            {
                context.Database.Create();
                context = new MyContext();
            }

            return context;

        }
    }
 }

Вот мой репозиторий:

public class DataRepository
{
    protected MyContext Context;

    public DataRepository(MyContext context = null)
    {
        Context = context ?? ContextProvider.Context;
    }

    public ProviderBase<Foo> FooProvider { get { return new ProviderBase<Foo>(); } }
    public ProviderBase<Bah> BahProvider { get { return new ProviderBase<Bah>(); } }

}

Класс ProviderBase

 public class ProviderBase<T> : IProviderBase<T> where T : BaseClass
    {
        public Boolean UseCaching { get; set; }

        public MyContext Context;

        public ProviderBase(Boolean useCaching = true, MyContext context = null)
        {
            Context = context ?? ContextProvider.Context;
            UseCaching = useCaching;
        }

        #region Implementation of IProviderBase<T>

        protected DbSet<T> DbSet
        {
            get
            {
                return Context.Set<T>();
            }
        }

        ... methods here for CRUD ....

    }

Я думаю, что проблема в статическом контексте, я прав?и если да, то каково решение?

Ответы [ 2 ]

4 голосов
/ 15 марта 2012

Не используйте статический контекст .

Чтобы изменить код, вы можете использовать это:

public class ContextProvider
{
    private const string ContextId = "EF.MyContext"; 

    // Call this only once in Application_Start in Global.asax
    public void InitializeDatabase() 
    {
        MyContext context = GetContext();
        if (!context.Database.Exists())
        {
            context.Database.Create(); 
        }
    }

    public MyContext GetContext()
    {
        MyContext context = HttpContext.Current.Items[ContextId] as MyContext;

        if (context == null)
        {
            context = new MyContext();
            HttpContext.Current.Items[CotnextId] = context; 
        }

        return context;
    }

    // Call this in EndRequest handler in Global.asax
    public void ReleaseContext()
    {
        MyContext context = HttpContext.Current.Items[ContextId] as MyContext;

        if (context != null)
        {
           context.Dispose();  
        } 
    }
 }

И ваш репозиторий будет выглядеть так:

public class DataRepository
{
    protected MyContext Context;

    // If you never need more than one instance of MyContext per repository you
    // can inject context directly and call provider in upper layer
    public DataRepository(ContextProvider provider)
    {
        Context = provider.GetContext();
    }

    public ProviderBase<Foo> FooProvider { get { return new ProviderBase<Foo>(); } }
    public ProviderBase<Bah> BahProvider { get { return new ProviderBase<Bah>(); } }
}
0 голосов
/ 15 марта 2012

Для одноэлементного паттерна очень полезна общая реализация Lazy:

public class ContextProvider 
{ 
    private static Lazy<MyContext> _context = new Lazy<MyContext> context(CreateContext); 

    private static MyContext CreateContext()
    {
            var context = new MyContext(); 

            Database.SetInitializer<MyContext>(null); 

            //create the DB if it doesn't exist 
            if (!context.Database.Exists()) 
            { 
                context.Database.Create(); 
            } 

            return context;
    }

    public static MyContext Context 
    { 
        get { return _context.Value;} 
    } 
 } 

Также, как уже указывали вам другие - не рекомендуется использовать статический контекст, а вместо этого создавать \ утилизировать его для каждой операции.

...