Ответ 1
1. Should i close it after every query?
.Net делает это для вас, поэтому пусть это обрабатывает, что задача сборщика мусора. Поэтому не беспокойтесь об утилизации своих объектов вручную, это хороший ответ от Jon Skeet: fooobar.com/questions/487223/.... Однако вы можете использовать оператор 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, если вы не собираетесь запускать тесты, удивительность этих шаблонов заключается в том, чтобы разделиться, чтобы вы могли тестировать и издеваться над потоком.
In-short: Если вы собираетесь запустить тест против вашего кода, перейдите по этим шаблонам. Если нет, я предоставляю вам пример о том, как вы могли бы поделиться своим контекстом данных между службами, которые вы хотели бы. Это ответ на ваш четвертый вопрос.
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, вы не хотите иметь дело с любым полным списком объектов.
EDIT:
Первое чтение:
- Эта ссылка относится к предварительно выпущенной версии EF6: Entity Framework и Async.
- Скотт Аллен опубликовал об этом в своем блоге: Async в Entity Framework 6.0.
- Если вы собираетесь использовать Единицу работы, я бы рекомендовал прочитать это: Сделать DbContext Ambient с UnitOfWorkScope.
- Дарин Димитров ответ на Выполняют ли асинхронные операции в ASP.NET MVC поток из ThreadPool на .NET 4.
Сделайте это:
(_context as IObjectContextAdapter).ObjectContext.Connection.Open();
Это отличная статья о Управление подключениями и транзакциями.
Структура Entity предоставляет EntityConnection через свойство Connection. Читайте как: public sealed class EntityConnection : DbConnection
.
Соображения для управления соединениями: (взято из предыдущей ссылки)
- Контекст объекта откроет соединение, если оно еще не открыто перед операцией. Если контекст объекта открывает соединение во время операции, он всегда будет закрывать соединение, когда операция будет завершена.
- Если вы вручную откроете соединение, контекст объекта не закроет его. Вызов Закрыть или Dispose закроет соединение.
- Если контекст объекта создает соединение, соединение всегда будет удаляться при размещении контекста.
- В долгосрочном контексте объекта вы должны убедиться, что контекст расположен, когда он больше не требуется.
Надеюсь, что это поможет.