В LINQ to SQL на основе репозиториев, мы должны создать новый DataContext в каждом методе? - PullRequest
2 голосов
/ 22 декабря 2009

например:

class repository {

     private DataContext db = new DataContext();

     public IQueryable<Blah> someMethod(int id){
         return from b in db.Blah ... select b;
}

     public IQueryable<Blah> someMethod2(int id){
         return from b in db.Blah ... select b;
}

     public IQueryable<Blah> someMethod3(int id){
         return from b in db.Blah ... select b;
}

}

OR

Должны ли мы создать новый DataContext в каждом из этих методов?

Я думаю, что у нас возникают некоторые ошибки, когда пользовательская нагрузка увеличивается из-за того, что у нас только ОДИН DataContext на экземпляр Repository, это точное предположение?

Ответы [ 3 ]

4 голосов
/ 22 декабря 2009

См. Также ответ на этот вопрос .

Короче говоря, особенно если вы используете шаблон репозитория, вы должны создать и утилизировать текст данных для каждой единицы работы. Обычно я использую что-то вроде:

public someclass someMethod(int id)
{
    using (var db = new SomeDataContext())
    {
        return db.FindMyClass(id);
    }
}
1 голос
/ 22 декабря 2009

Что я сделал лично, так это сделал хранилище одноразовым. Затем вы получаете конструкции, такие как:

void DeleteCustomer(int id)
{
    using(var repos = GetRepos())
    {
        var customer = repos.GetAll<Customer>().Single(x => x.Id == id);
        repos.Delete(customer);
        repos.SaveChanges();
    }
}

Это можно реализовать, создав контекст в репозитории ctor и разместив его в реализации Dispose().

Вы должны убедиться, что вы не добавляете, не меняете, не удаляете объекты и не выбираете из одного контекста. Создается контекст для «последней» единицы работы.

Вы должны быть осторожны с такими вещами, как это:

IQueryable<Customer> GetCustomers()
{
    using(var repos = GetRepos())
    {
        return repos.GetAll<Customer>();
    }
}

void Test()
{
    // This will throw an exception, because it extends the linq query
    // while the context is disposed.
    var customers = GetCustomers().Where(x => x.Id == 123); 
}

В этом случае лучше переместить хранилище как можно дальше:

IQueryable<Customer> GetCustomers(MyRepository repos)
{
    return repos.GetAll<Customer>();
}

void Test()
{
    using(var repos = ...)
    {
        var customers = GetCustomers(repos).Where(x => x.Id == 123); 
    }
}
1 голос
/ 22 декабря 2009

Я знаю, что это не совсем то же самое, но на интенсивно используемом сайте asp.net, использующем устаревшие адаптеры данных, я использовал, чтобы открывать соединение с базой данных на странице init и закрывать ее при предварительном просмотре страницы. Однако я обнаружил, что, когда сайт стал более загруженным, страницы начали сканировать. Я где-то читал, что всегда лучше открывать как можно позже и закрывать как можно раньше.

Теперь я открываю контекст в каждом методе, однако из-за linq 2 sql и его отложенного выполнения я не уверен, имеет ли это большое значение.

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

...