Как очистить кеш 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 - мой контекст.