Подтвердить что ты не робот

В LINQ-SQL оберните DataContext, используя инструкцию - pros cons

Может ли кто-то изложить мнение о плюсах и минусах между переносом DataContext в оператор using или нет в LINQ-SQL с точки зрения факторов, таких как производительность, использование памяти, простота кодирования, правильная вещь и т.д.

Обновление. В одном конкретном приложении я испытал, что, не обертывая DataContext в использовании блока, объем использования памяти увеличивался, поскольку живые объекты не были выпущены для GC. Как и в примере ниже, если я держу ссылку на объект "Список объектов q" и получаю доступ к объектам q, я создаю граф объектов, который не выпущен для GC.

DataContext с использованием

    using (DBDataContext db = new DBDataContext())
    {
        var q = 
            from x in db.Tables
            where x.Id == someId
            select x;

        return q.toList();
    }

DataContext без использования и сохранения

  DBDataContext db = new DBDataContext()
  var q = 
        from x in db.Tables
        where x.Id == someId
        select x;

    return q.toList(); 

Спасибо.

4b9b3361

Ответ 1

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

DataContext превращается в объект короткого использования, использует его, получает часть выполняемой работы, вытаскивает... именно то, что вы делаете при использовании.

Итак, преимущества:

  • Более быстрые закрытые соединения
  • Свободная память из распоряжения (кешированные объекты в контенте)

Даунсайд - больше кода? Но это не должно быть сдерживающим фактором, вы используете здесь using.

Посмотрите на ответ Microsoft: http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/2625b105-2cff-45ad-ba29-abdd763f74fe

Короткий вариант, если вам нужно использовать using/.Dispose():

Короткий ответ; нет, вам это не нужно, но вы должны...

Ответ 2

Ну, это a IDisposable, поэтому я думаю, это не плохая идея. Люди в MSFT сказали, что они сделали DataContexts максимально легкими, чтобы вы могли создавать их с безрассудным отказом, поэтому вы, вероятно, не получаете много, хотя.....

Ответ 3

  • Впервые DataContext получит объект из БД.
  • В следующий раз, когда вы запускаете запрос для получения одного и того же объекта (такие же параметры): вы увидите запрос в профилировщике, но ваш объект в DataContext не будет заменен новым из DB!!

Не говоря уже о том, что за каждым DataContext - это идентификационная карта всех объектов, которые вы запрашиваете из БД (вы не хотите держать это в стороне).

Вся идея DataContext Единица работы с Оптимистичной Concurrency. Используйте его для короткой транзакции (только для отправки) и утилизации.

Лучший способ не забыть dispose - использовать().

Ответ 4

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

Если, с другой стороны, ваш уровень данных может ожидать множественные последовательные вызовы из бизнес-уровня, вы можете повторно создавать/удалять DataContext для каждой большей последовательности вызовов. не идеально.

Я сделал, чтобы создать объект Data Layer как IDisposible. Когда он создается, создается DataContext (или действительно, после первого вызова метода), и когда объект Data Layer находится, он закрывает и удаляет DataContext.

вот как это выглядит:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;

namespace PersonnelDL
{
    public class PersonnelData : IDisposable
    {
        #region DataContext management
        /// <summary>
        /// Create common datacontext for all data routines to the DB
        /// </summary>
        private PersonnelDBDataContext _data = null;
        private PersonnelDBDataContext Data
        {
            get
            {
                if (_data == null)
                {
                    _data = new PersonnelDBDataContext(ConfigurationManager.ConnectionStrings["PersonnelDB"].ToString());
                    _data.DeferredLoadingEnabled = false; // no lazy loading
                    //var dlo = new DataLoadOptions(); // dataload options go here
                }
                return _data;
            }
        }

        /// <summary>
        /// close out data context
        /// </summary>
        public void Dispose()
        {
            if (_data != null)
                _data.Dispose();
        }
        #endregion

        #region DL methods
        public Person GetPersonByID(string userid)
        {
            return Data.Persons.FirstOrDefault(p => p.UserID.ToUpper().Equals(userid.ToUpper()));
        }

        public List<Person> GetPersonsByIDlist(List<string> useridlist)
        {
            var ulist = useridlist.Select(u => u.ToUpper().Trim()).ToList();
            return Data.Persons.Where(p => ulist.Contains(p.UserID.ToUpper())).ToList();
        }

        // more methods...
        #endregion
    }
}

Ответ 5

В одном конкретном приложении я испытал это, не обернув блок DataContext in using, объем использования памяти продолжал расти, поскольку живые объекты не были выпущены для GC. Как и в примере ниже, если я держу ссылку на объект List<Table> и объекты доступа q, я создаю граф объектов, который не выпущен для GC.

DBDataContext db = new DBDataContext()
var qs = 
    from x in db.Tables
    where x.Id == someId
    select x;

return qs.toList();

foreach(q in qs)
{
    process(q);
    // cannot dispose datacontext here as the 2nd iteration 
    // will throw datacontext already disposed exception 
    // while accessing the entity of q in process() function
    //db.Dispose();
}

process(Table q)
{
    // access entity of q which uses deferred execution
    // if datacontext is already disposed, then datacontext 
    // already disposed exception is thrown
}

В этом примере я не могу избавиться от datacontext, потому что все экземпляры Table в переменной списка qs ** используют один и тот же файл datacontext. После Dispose() доступ к объекту в process(Table q) выдает исключающее исключение datacontext.

Уродливое kluge, для меня, заключалось в том, чтобы удалить все ссылки на объекты для объектов q после цикла foreach. Лучше всего, конечно, использовать оператор using.

Насколько мне известно, я бы использовал инструкцию using.