Как очистить кеш DataContext от Linq до Sql

Я использую Linq to Sql для запроса некоторой базы данных, я использую Linq только для чтения данных из БД, и я вношу изменения в нее другими способами. (Это не может быть изменено, это ограничение от приложения, которое мы расширяем, все обновления должны проходить через его sdk).

Это хорошо, но я сталкиваюсь с некоторыми проблемами с кешем, в основном, я запрашиваю строку с использованием Linq, затем я удаляю ее через внешние средства, а затем создаю новую строку извне, если я снова запрашиваю эту строку, используя linq я получили старые (кэшированные) данные.

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

Есть ли способ очистить кеш DataContex?

Я нашел метод sufring net, но он не выглядит безопасным: http://blog.robustsoftware.co.uk/2008/11/clearing-cache-of-linq-to-sql.html

Как вы думаете? какие у меня варианты?

Ответы

Ответ 1

Если вы хотите обновить конкретный объект, лучше всего использовать Refresh().

Вот так:

Context.Refresh(RefreshMode.OverwriteCurrentValues, objectToRefresh);

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

Update

Я вижу, о чем вы говорите в комментариях, в рефлекторе вы видите, что это происходит внутри .Refresh():

object objectByKey = context.Services.GetObjectByKey(trackedObject.Type, keyValues);
if (objectByKey == null)
{
    throw Error.RefreshOfDeletedObject();
}

Метод, который вы связываете, является вашим лучшим вариантом, класс DataContext не предоставляет другого способа очистки удаленной строки. Проверки на удаление и т.д. Находятся внутри метода ClearCache()... он действительно просто проверяет удаление и вызывает ResetServices() на CommonDataServices под ним. Единственный плохой эффект - это очистка любых ожидающих вставок, обновлений или удалений, которые вы поставили в очередь.

Есть еще один вариант: можете ли вы запустить другой DataContext для любой операции, которую вы делаете? У него не было бы никакого кеша... но это связано с некоторыми вычислительными затратами, поэтому, если ожидающие вставки, обновления и удаления не являются проблемой, я бы придерживался подхода ClearCache().

Ответ 2

Вы должны иметь возможность просто запрашивать результирующие наборы, которые используют эти объекты. Это не потянет кешированный набор, но фактически вернет окончательные результаты. Я знаю, что это может быть не так просто или возможно в зависимости от того, как вы настраиваете приложение...

НТН.

Ответ 3

Я сделал этот код действительно CLEAR "кэшированных" сущностей, отсоединив его.

var entidades = Ctx.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified | EntityState.Unchanged);
foreach (var objectStateEntry in entidades)
    Ctx.Detach(objectStateEntry.Entity);

Где Ctx - мой контекст.