LINQ TO SQL Я что-то упускаю здесь очевидное? - PullRequest
1 голос
/ 28 октября 2009

У меня есть этот метод, который будет вызываться из клиента WCF, но для моего тестирования я использую локальную «ссылку на проект». Я получаю сообщение об ошибке, что не могу вызвать DataContext после его удаления.

    public IEnumerable<Server> GetServers()
    {
        // initialze to null
        ServersDataContext sdc = null;

        try
        {
            // get connected
            using (sdc = GetDataContext())
            {
                // disable this deferred loading
                sdc.DeferredLoadingEnabled = false;

                var relations = from svr in sdc.Servers; // complex linq here

                // return
                return relations;
            }
        }
        catch (Exception ex)
        {
            LogError(ex, "fwizs.Internal");
            throw;
        }
        finally
        {
            if (sdc != null)
            {
                sdc.Dispose();
            }
        }
    }

А вот как я использую метод, который выдает эту ошибку: «Не удается получить доступ к удаленному объекту».

    if (da.GetServers()
        .Select(sv => sv.ServerID == s.ServerID).Count() == 0)
    {

        // do work since we found it
    }

Используя метод .Select () для этого возвращаемого объекта IEnumerable пытается выполнить откат к базе данных, чтобы сделать выбор. После сериализации для WCF я не думаю, что это будет проблемой, но я бы хотел, чтобы мои локальные тесты работали.

Ответы [ 6 ]

4 голосов
/ 28 октября 2009

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

Вы можете просто использовать метод ToList, чтобы убедиться, что данные загружены в память:

return relations.ToList();
4 голосов
/ 28 октября 2009

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

var relations = from svr in sdc.Servers;

return relations.ToList();
3 голосов
/ 28 октября 2009

LINQ является ленивым, поэтому запрос определяется только здесь, а не повторяется.

Итак, вы определяете запрос, а затем закрываете текстовый текст. Вскоре после этого вы пытаетесь выполнить итерацию через, что означает, что вы пытаетесь запросить через соединение SQL, которое было закрыто ранее.

Из MSDN:

Этот метод реализован с использованием отложенного выполнения. Немедленное возвращаемое значение - это объект, в котором хранится вся информация, необходимая для выполнения действия. Запрос, представленный этим методом, не выполняется до тех пор, пока объект не будет перечислен путем непосредственного вызова его метода GetEnumerator или использования foreach в Visual C # или For Each в Visual Basic.

2 голосов
/ 28 октября 2009

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

0 голосов
/ 28 октября 2009

В дополнение к тому, что другие говорили об использовании .ToList, это также должно работать и с ленивым исполнением:

public IEnumerable<Server> GetServers() {
    // initialze to null
    ServersDataContext sdc = null;
    try {
        // get connected
        using (sdc = GetDataContext()) {
            // disable this deferred loading
            sdc.DeferredLoadingEnabled = false;
            foreach (var relation in from svr in sdc.Servers) // complex linq here
                yield return relations;
        }
    }
    catch (Exception ex) {
        LogError(ex, "fwizs.Internal");
        throw;
    }
    finally {
        if (sdc != null) {
            sdc.Dispose();
        }
    }
}
0 голосов
/ 28 октября 2009

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

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