Entity Framework - обновить объекты из базы данных

У меня проблемы с обновлением объектов в моей базе данных. У меня есть два ПК и два приложения.

На первом ПК есть приложение, которое взаимодействует с моей базой данных и добавляет некоторые данные в таблицу измерений. На другом моем ПК есть приложение, которое извлекает последние измерения по таймеру, поэтому оно должно также извлекать измерения, добавленные приложением на моем первом ПК.

Проблема в том, что это не так. При запуске моего приложения оно кэширует все данные из базы данных и никогда не добавляет новые данные. Я использую метод Refresh(), который хорошо работает, когда я изменяю какие-либо кэшированные данные, но не обновляет вновь добавленные данные.

Вот мой метод, который должен обновлять данные:

    public static Entities myEntities = new Entities();

    public static Measurement GetLastMeasurement(int conditionId)
    {
        myEntities.Refresh(RefreshMode.StoreWins, myEntities.Measurements);

        return (from measurement in myEntities.Measurements
                where measurement.ConditionId == conditionId
                select measurement).OrderByDescending(cd => cd.Timestamp).First();
    }

P.S. Приложения имеют разные строки подключения в app.config (разные учетные записи для одной и той же БД).


person Nebojsa Veron    schedule 01.04.2010    source источник
comment
Вы можете проверить мой ответ здесь stackoverflow.com/questions/1746941/objectcontext-refresh   -  person Christian Rodriguez    schedule 13.06.2013


Ответы (3)


Это должно работать:

public static Entities myEntities = new Entities();

public static Measurement GetLastMeasurement(int conditionId)
{
    myEntities.Refresh(RefreshMode.StoreWins, myEntities.Measurements);
    var allMeasurements = myEntities.Measurements.ToList();//retrieves all measurements from database

    return (from measurement in allMeasurements
            where measurement.ConditionId == conditionId
            select measurement).OrderByDescending(cd => cd.Timestamp).First();
}

Какой смысл в кэшировании, когда вы обновляете хранилище каждый раз, когда хотите его использовать? Вы можете изменить его на:

public Measurement GetLastMeasurement(int conditionId)
{
    var entities = new Entities();
    return (from measurement in entities.Measurements
            where measurement.ConditionId == conditionId
            select measurement).OrderByDescending(cd => cd.Timestamp).First();
}

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

person LukLed    schedule 02.04.2010
comment
Первое упомянутое вами решение по-прежнему не извлекает новые добавленные данные из моей базы данных. Ваше второе решение, которое, как я ожидал, сработает, тоже не работает. Я бы не предпочел это, потому что таким образом я открываю новый контекст в своей базе данных каждый раз, когда хочу получить последнее измерение. Когда я перезапускаю свое приложение, оно извлекает новые данные, но не извлекает, если что-то добавлено во время работы приложения. Возможно ли, что причиной этого являются разные учетные записи, которые я использую для каждого приложения (тот, который добавляет, и тот, который извлекает данные из БД)? - person Nebojsa Veron; 02.04.2010
comment
С любым из этих двух решений я получаю то же самое, что и раньше. Если я редактирую строку в таблице измерений (которая была получена при запуске приложения), она обновляется. Но если я добавлю новую строку, она не будет ее извлекать. В обоих случаях. На этот раз я отредактировал существующую и добавил новую строку непосредственно с помощью SQL Manangement Studio. - person Nebojsa Veron; 03.04.2010
comment
@Nebo: Вы уверены, что делаете это правильно? У вас есть SQL Profiler? Вы можете посмотреть на выполненный SQL? - person LukLed; 03.04.2010
comment
Хм, у меня странная проблема. На самом деле оба решения работают хорошо, просто моя привязка не обновляется. Я должен это выяснить. Спасибо! - person Nebojsa Veron; 03.04.2010

Начиная с EF 4.1 вы можете использовать метод AsNoTracking() для своих объектов.

return myEntities.Measurements.AsNoTracking();

Обратите внимание, что AsNoTracking() не добавит объекты в ваш контекст для отслеживания, а просто вернет их свежими из вашего хранилища данных.

Для получения дополнительной информации см. http://blogs.msdn.com/b/adonet/archive/2011/02/05/using-dbcontext-in-ef-feature-ctp5-part-11-load-and-asnotracking.aspx

person Rei Mavronicolas    schedule 08.06.2012

Другая возможность — использовать MergeOption, чтобы решить, как вы хотите управлять объектами в контексте. Например, MergeOption.OverwriteChanges перезапишет контекст объекта значениями из источника данных.

Дополнительные сведения см. на странице http://msdn.microsoft.com/en-us/library/system.data.objects.mergeoption.aspx

person Matt    schedule 12.08.2012