Обновить DataContext при использовании шаблона репозитория, возвращающего данные IQueryable - PullRequest
1 голос
/ 21 февраля 2012

У меня есть отдельная проблема с кэшированными данными в веб-приложении, и я понимаю, что они кэшируются из-за повторного использования текста данных.Мои классы репозитория возвращают типы IQueryable, поэтому я не могу обновить текст данных, закрыв и снова открыв его.Например, мой CustomerRepository имеет этот конструктор datacontext:

private CAClassesDataContext context = new CAClassesDataContext();

И все методы взаимодействия с базой данных затем используют этот контекст, например:

public IQueryable<Customer> Customers
{
     get { return context.Customers; }
}

Если я пытаюсь использовать контекст в использованииblock:

using(CAClassesDataContext context = new CAClassesDataContext())
{
...
}

Я не могу получить доступ к связанным классам, так как используется отложенная загрузка.Я попытался добавить:

context.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, customer)

после обновления, но проблема все еще существует.Как заставить LINQ to SQL использовать данные базы данных вместо кэшированных?

ОБНОВЛЕНИЕ : Благодаря ответам Стива и Эндрю я смог решить эту проблему.Мои репозитории теперь имеют конструктор, подобный этому:

[Inject]
public CustomerRepository (CAClassesDataContext Context)
{
    context = Context;
}

И в моих привязках Ninject добавлено:

Bind<CAClassesDataContext>().ToSelf().InRequestScope();

В моем проекте используется пользовательский поставщик членства, и я не смог использовать вышеописанную техникуиз-за провайдера без параметров конструктора.Чтобы обойти это, я добавил в репозиторий методы, которые вызываются до и после поиска в базе данных:

repository.CreateContext();
var cust = repository.GetAllCustomers().SingleOrDefault(c => c.Username == username);
repository.DisposeContext();

Ответы [ 2 ]

1 голос
/ 21 февраля 2012

Контекст данных должен существовать только во время «единицы работы». Похоже, вы неправильно используете свой DC и держите его (или класс репозитория) дольше, чем следовало бы.

Попробуйте создавать экземпляры хранилища каждый раз, когда вашему BLL необходимо выполнить ряд операций с базой данных, и утилизируйте его по окончании. Или это непрактично (например, если вы используете IoC для внедрения экземпляра репозитория в свой BLL), возможно, добавьте метод в репозиторий, чтобы позволить BLL раскрутить DC до запуска единицы работы, и другой метод чтобы утилизировать его потом.

0 голосов
/ 21 февраля 2012

Как говорит @Andrew Stephens, ваш контекстный объект должен создаваться и использоваться для каждого запроса.

Вместо того, чтобы жестко программировать его для создания внутри хранилища, вставьте его в хранилище черезего конструктор.Если вы используете контейнер IoC, у вас может быть возможность управлять контекстом для каждого отдельного запроса (например, Ninject предоставляет это), в противном случае вы можете заключить свой контекст в объект хранилища данных в области запроса, используяHttpContext.Items, как описано в этой статье .

...