linq2sql: одиночный элемент или использование, лучшие практики

что является предпочтительной практикой когда использование linq2sql (в asp.net mvc приложения): создать "одиночный элемент" для DataContext как:

partial class db
{
    static db _db = new db(global::data.Properties.Settings.Default.nanocrmConnectionString, new AttributeMappingSource());

    public static db GetInstance()
    {
        return _db;
    }
}

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

using (db _db = new db())
{
    ...
}

использование using приносит некоторые ограничения в код. таким образом, я предпочитаю использовать одиночный элемент один. это - странная практика?

UPD:
объяснение, почему я использую одиночный элемент:

public class UserGroupRepository
{
    public static IQueryable<Group> RolesFor(string username)
    {
        User user = UserRepository.WithUsername(username);

        return from g in db.GetInstance().Groups
                join ug in db.GetInstance().UsersGroups on g.Id equals ug.GroupId
                where ug.UserId == user.Id
                select g;
    }
}

у меня есть этот метод. из-за него возвращает IQueryable - я могу продолжить составлять запрос без него выполнение, таким образом, здесь просто ленивые возвраты результата.
если я переписываю тот же код с using - я не могу смочь возвратить IQueryable (потому что дб будет расположен, и IQueryable будет потерян также), и я изменил бы его для Списка. и теперь этот метод возвратит "огромный" Список, из которого я отфильтрую данные по предыдущей функции.

я надеюсь, что описываю достаточно детализированное.

7
задан Jedidja 23 April 2010 в 10:01
поделиться

3 ответа

Контексты данных Linq to Sql НЕ являются потокобезопасными, и должен использоваться только в контексте одного потока. Использование шаблона singleton не только противоречит стандартным методам linq2sql, но и приведет к серьезным проблемам, если ваше приложение подвергнется серьезной нагрузке.

РЕДАКТИРОВАТЬ:

В ответ на ваши ограничения относительно блока using попробуйте реализовать свой метод RolesFor как метод расширения:

public static IQueryable<Group> GetUserRoles(this Database db, string username)
{
        return from g in db.GetInstance().Groups
                join ug in db.GetInstance().UsersGroups on g.Id equals ug.GroupId
                where ug.UserId == user.Id
                select g;
}

Это позволит вам вызывать ваш метод внутри блока using из любого места:

using(Database db = createContext())
{
     IQueryable<Group> queryable = db.GetUserRoles("MyUsername");
     // from here on you can query the queryable object
     var groups = (from g in queryable
                   where g.Name == "MyRole"
                   select g).ToList();
}

РЕДАКТИРОВАТЬ 2

В ответ на ваш комментарий об открытии другого соединения с сервером sql для каждого экземпляра контекста данных. Создание контекста данных не откроет соединение с сервером sql, но каждая фактическая операция будет. Независимо от того, создаете ли вы 1 или 4 контекста данных, если вы выполняете 4 операции с базой данных, будет открыто 4 соединения sql. Однако имейте в виду, что .NET использует пул подключений к серверу sql, поэтому для каждой операции не требуется создание полностью нового SqlConnection, а требуется только извлечение существующего из пула подключений и повторное открытие подключения

5
ответ дан 7 December 2019 в 07:42
поделиться

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

Google выполняет поиск по запросу «контекст объекта в веб-области» или «время существования контекста объекта» (или контекст данных для l2s).

например. http://dotnetslackers.com/articles/ado_net/Managing-Entity-Framework-ObjectContext-lifespan-and-scope-in-n-layered-ASP-NET-applications.aspx

В MVC2 вы можете поместить код управления контекстом в вашем базовом классе контроллера.

0
ответ дан 7 December 2019 в 07:42
поделиться

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

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

2
ответ дан 7 December 2019 в 07:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: