我首先为EF 4.2代码工作,并且已经遇到了很多随机的上下文连接问题,并且想知道你是否可以关注这个实现,然后拍我的手腕做错了(如果是错的话) )
我为这个项目开发了一个存储库模式。
我确信我这样做的方法是问题,但无论如何这里是代码:
Context Provider
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 Class
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 ....
}
我认为问题是静态上下文,对吗?如果是的话,解决方案是什么?
答案 0 :(得分:4)
要修改代码,您可以使用:
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>(); } }
}
答案 1 :(得分:-1)
对于单例模式,有一个非常有用的通用实现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;}
}
}
正如其他人已经指出的那样 - 不建议使用静态上下文,而是为每个操作创建\配置它。