LINQ to SQL: повторное использование DataContext - PullRequest
1 голос
/ 14 декабря 2010

У меня есть несколько статических методов, которые выполняют простые операции, такие как вставка или удаление записи.Все эти методы следуют этому шаблону using:

public static UserDataModel FromEmail(string email)
{
    using (var db = new MyWebAppDataContext()) 
    {
        db.ObjectTrackingEnabled = false;
        return (from u in db.UserDataModels
                where u.Email == email
                select u).Single();
    }
}

У меня также есть несколько методов, которые должны выполнять несколько операций, использующих DataContext:

public static UserPreferencesDataModel Preferences(string email)
{
    return UserDataModel.Preferences(UserDataModel.FromEmail(email));
}

private static UserPreferencesViewModel Preferences(UserDataModel user)
{
    using(var db = new MyWebAppDataContext()) 
    {
        var preferences = (from u in db.UserDataModels
                          where u == user
                          select u.Preferences).Single();

        return new UserPreferencesViewModel(preferences);
    }
}

Мне нравитсячто я могу разделить простые операции на искусственно хранимые процедуры в моих моделях данных с помощью статических методов, таких как FromEmail(), но меня беспокоит стоимость Preferences() вызова двух соединений (верно?) через два оператора using DataContext.

Должен ли я быть?То, что я делаю, менее эффективно, чем использование одного оператора using(var db = new MyWebAppDataContext())?

Ответы [ 5 ]

2 голосов
/ 14 декабря 2010

Если вы исследуете эти «две» операции, вы можете увидеть, что они могут быть выполнены за одну поездку в одну базу данных. Минимизация циклических обращений к базе данных является основной целью производительности (второй после минимизации базы данных io).

Если у вас есть несколько точек данных, они по-разному видят одну и ту же запись. Обычно ObjectTracking требует, чтобы один и тот же экземпляр всегда использовался для представления одной записи. Если у вас есть 2 объекта DataContexts, каждый из них самостоятельно отслеживает объекты на своих экземплярах.

Предположим, что запись изменяется между DC1, наблюдающим его, и DC2, наблюдающим его. В этом случае запись будет не только иметь 2 разных экземпляра, но эти разные экземпляры будут иметь разные значения . Может быть очень сложно выразить бизнес-логику против такой движущейся цели.

Вы должны окончательно удалить DataContext после UnitOfWork, чтобы защитить себя от устаревших экземпляров записей.

1 голос
/ 14 декабря 2010

Я также думаю, что создание нового DataContext каждый раз является правильным способом, но эта ссылка объясняет различные подходы к обработке контекста данных. Linq to SQL DataContext Lifetime Management

1 голос
/ 14 декабря 2010

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

Использование пула соединений, так что это не слишком дорогая операция.

1 голос
/ 14 декабря 2010

Обычно вы должны использовать один контекст для одной логической единицы работы.Итак, взгляните на единицу работы шаблона, напр.http://dotnet.dzone.com/news/using-unit-work-pattern-entity

0 голосов
/ 14 декабря 2010

Я разработал компонент-оболочку, который использует интерфейс вроде:

public interface IContextCacher {
    DataContext GetFromCache();
    void SaveToCache(DataContext ctx);
}

И использовать обертку для создания экземпляра контекста; если он существует в кеше, он извлекается оттуда, в противном случае создается новый экземпляр и передается в метод Save, и все будущие реализации будут получать значение из метода получения.

В зависимости от типа приложения будет действительный механизм кэширования. Скажем, например, веб-приложение ASP.NET. Это может хранить контекст в коллекции элементов, поэтому он доступен только для запроса. Для приложения для Windows, оно может извлечь его из некоторой коллекции синглтонов. Это может быть все, что вы хотели под сценой.

...