1. Should i close it after every query?
.Net 会为你做这件事,所以让它处理它,这是一个垃圾收集器任务。所以不要费心手动处理你的对象,这是 Jon Skeet 的一个很好的答案:https ://stackoverflow.com/a/1998600/544283 。但是,您可以使用该using(IDisposable){ }
语句来强制 GC 完成它的工作。这是一篇关于资源重新分配的好文章:http: //www.codeproject.com/Articles/29534/IDisposable-What-Your-Mother-Never-Told-You-About。
2. A connection in static class is good?
永远不要使数据上下文静态!数据上下文不是线程安全的或并发安全的。
3. Is there a good design pattern for this problem?
正如 Belogix 提到的依赖注入和工作单元模式很棒,实际上实体框架本身就是一个工作单元。不过,DI 和 UoW 有点被高估了,如果这是您第一次处理 IoC 容器,那么实施起来并不容易,如果您要走这条路,我会推荐 Ninject。另一件事是,如果您不打算运行测试,您实际上并不需要 DI,这些模式的美妙之处在于解耦,因此您可以毫不费力地进行测试和模拟。
简而言之:如果您要针对您的代码运行测试,请选择这些模式。如果没有,我将为您提供一个示例,说明如何在您想要的服务之间共享您的数据上下文。这是你第四个问题的答案。
4. What is the best method for making database connection (static, per request)?
您的上下文服务:
public class FooContextService {
private readonly FooContext _ctx;
public FooContext Context { get { return _ctx; } }
public FooContextService() {
_ctx = new FooContext();
}
}
其他服务:
public class UnicornService {
private readonly FooContext _ctx;
public UnicornService(FooContextService contextService) {
if (contextService == null)
throw new ArgumentNullException("contextService");
_ctx = contextService.Context;
}
public ICollection<Unicorn> GetList() {
return _ctx.Unicorns.ToList();
}
}
public class DragonService {
private readonly FooContext _ctx;
public DragonService(FooContextService contextService) {
if (contextService == null)
throw new ArgumentNullException("contextService");
_ctx = contextService.Context;
}
public ICollection<Dragon> GetList() {
return _ctx.Dragons.ToList();
}
}
控制器:
public class FantasyController : Controller {
private readonly FooContextService _contextService = new FooContextService();
private readonly UnicornService _unicornService;
private readonly DragonService _dragonService;
public FantasyController() {
_unicornService = new UnicornService(_contextService);
_dragonService = new DragonService(_contextService);
}
// Controller actions
}
第二个想法(几乎是一个编辑):如果您需要您的上下文不为您的实体创建代理,因此也没有延迟加载,您可以重载您的上下文服务,如下所示:
public class FooContextService {
private readonly FooContext _ctx;
public FooContext Context { get { return _ctx; } }
public FooContextService() : this(true) { }
public FooContextService(bool proxyCreationEnabled) {
_ctx = new FooContext();
_ctx.Configuration.ProxyCreationEnabled = proxyCreationEnabled;
}
}
笔记:
- 如果您将启用代理创建设置为 false,您将不会有开箱即用的延迟加载。
- 如果你有 api 控制器,你不想处理任何完整的对象图。
编辑:
先读一些:
完成这个:
(_context as IObjectContextAdapter).ObjectContext.Connection.Open();
这是一篇关于管理连接和事务的好文章。
实体框架通过 Connection 属性公开 EntityConnection。读作:public sealed class EntityConnection : DbConnection
。
管理连接的注意事项:(取自上一个链接)
- 如果在操作之前对象上下文尚未打开,则对象上下文将打开连接。如果对象上下文在操作期间打开了连接,那么它总是会在操作完成时关闭连接。
- 如果手动打开连接,对象上下文不会关闭它。调用Close或Dispose将关闭连接。
- 如果对象上下文创建了连接,则在释放上下文时始终会释放连接。
- 在长时间运行的对象上下文中,您必须确保在不再需要上下文时将其释放。
希望能帮助到你。