Ошибка при использовании службы данных WCF - PullRequest
2 голосов
/ 29 июня 2011

Я следую этому руководству и получаю сообщение об ошибке.Может кто-нибудь мне помочь?

Код для моей модели данных указан ниже

  namespace Datalayer {
    public class DataModel {

        public DataModel()
        {
            using (btWholesaleDataContext db = new btWholesaleDataContext()) {
                //! requires auth
                var MACRequestList = from r in db.btRequests
                                     select new Models.BT.Request {
                                         ID = r.ID,
                                         Date = r.DateTime,
                                         StatusCode = 3,
                                         Status = r.Status
                                     };

                MACRequests = MACRequestList.AsQueryable();

            }
        }

        public IQueryable<Models.BT.Request> MACRequests { get; private set; }
    }
}

Веб-служба выдает ошибку

Невозможно получить доступ к удаленному объекту. Имя объекта: 'DataContext, доступный послеDispose.

Когда я получаю доступ к MACRequests

Я отправил только код, который, по моему мнению, не работает.Если вы хотите увидеть больше, просто дайте мне знать.

Ответы [ 4 ]

4 голосов
/ 29 июня 2011

Ваш контекст данных располагается в конце вашего конструктора, в конце блока using { }. Однако, когда вы используете свойство IQueryable MACRequests, ему нужен тот базовый контекст, который с тех пор был удален.

Один из возможных способов справиться с этим - сделать ваш класс IDisposable и расположить контекст таким образом:

public class DataModel : IDisposable {

    private btWholesaleDataContext wholesaleDataContext;

    public DataModel()
    {
        wholesaleDataContext = new btWholesaleDataContext();
        //! requires auth
        var MACRequestList = ... ;

        MACRequests = MACRequestList.AsQueryable();
    }

    public IQueryable<Models.BT.Request> MACRequests { get; private set; }

    public void Dispose() {
        if(wholesaleDataContext != null)
            wholesaleDataContext.Dispose();
    }
}

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

Другая альтернатива - сделать MACRequests фактическим списком предметов вместо IQueryable:

public class DataModel {

    public DataModel()
    {
        using (btWholesaleDataContext db = new btWholesaleDataContext()) {
            //! requires auth
            var MACRequestList = ... ;

            MACRequests = MACRequestList.ToList(); // ToList reads the records now, instead of later.

        }
    }

    public List<Models.BT.Request> MACRequests { get; private set; }
}
2 голосов
/ 29 июня 2011

Я думаю, это потому, что вы используете IQueryable <>.Его лениво запрашивает служба.Вместо этого используйте List <>, чтобы он немедленно запрашивал

или превращал "btWholesaleDataContext db" в переменную-член

1 голос
/ 29 июня 2011

Запросы к MACRequest откладываются - как только вы выйдете из блока using и ваш DataContext будет удален, вы не сможете выполнить требуемый запрос.

0 голосов
/ 29 июня 2011

Вы создаете контекст данных в блоке using в конструкторе вашей DataModel ... поэтому к моменту обращения к MAC-запросам контекст данных был удален.

Обратите внимание на следующее:

public class DataModel : IDisposable {
    btWholesaleDataContext db = new btWholesaleDataContext();

    public void Dispose() 
    {
        btWholesaleDataContext.Dipose();
    }

    public IQueryable<Models.BT.Request> MACRequests { 
          get {
                                 return from r in db.btRequests
                                 select new Models.BT.Request {
                                     ID = r.ID,
                                     Date = r.DateTime,
                                     StatusCode = 3,
                                     Status = r.Status
                                 };
          } 
    }
}

Обратите внимание, что это использование будет работать:

using (var dm = new DataModel())
{
   dm.MACRequests.ToArray();
}

, но это не удастся по той же причине, что и оригинал:

IQueryable<Models.BT.Request> requests = null;

using (var dm = new DataModel())
{
   requests = dm.MACRequests;
}   

// this will fail because the context is disposed by the time we force enumeration of the query
requests.ToArray();

... В качестве альтернативы, поскольку службы данных WCF не могут фильтровать проекции, и, таким образом, все, что вы действительно можете сделать с запросом

                                     from r in db.btRequests
                                     select new Models.BT.Request {
                                         ID = r.ID,
                                         Date = r.DateTime,
                                         StatusCode = 3,
                                         Status = r.Status
                                     };

, это выполнить его ...

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...