Обновить экземпляр объекта с помощью DbContext

С EF4 CTP5 DbContext, что эквивалентно этому

    public void Refresh(Document instance)
    {
        _ctx.Refresh(RefreshMode.StoreWins, instance);
    }

Я пробовал это, но это не то же самое, обновление экземпляра

    public void Refresh(Document instance)
    {
        _ctx.ChangeTracker.DetectChanges();
    }

?


person mare    schedule 07.03.2011    source источник


Ответы (3)


Вы должны использовать это:

public void Refresh(Document instance)
{
  _ctx.Entry<Document>(instance).Reload();
}
person Ladislav Mrnka    schedule 07.03.2011

Вышеуказанное не работает. Метод Reload() некорректно обновляет сущность из базы данных. Он выполняет запрос выбора SQL, но не создает прокси для навигационных свойств. См. пример ниже (я использую базу данных Northwind в SQL Server с EF 5.1):

NorthwindEntities northwindEntities = new NorthwindEntities();
Product newProduct = new Product
{
    ProductName = "new product",
    Discontinued = false,
    CategoryID = 3
};
northwindEntities.Products.Add(newProduct);
northwindEntities.SaveChanges();

// Now the product is stored in the database. Let's print its category

Console.WriteLine(newProduct.Category); // prints "null" -> navigational property not loaded

// Find the product by primary key --> returns the same object (unmodified)
// Still prints "null" (due to caching and identity resolution)
var productByPK = northwindEntities.Products.Find(newProduct.ProductID);
Console.WriteLine(productByPK.Category); // null (due to caching)

// Reloading the entity from the database doesn't help!
northwindEntities.Entry<Product>(newProduct).Reload();
Console.WriteLine(newProduct.Category); // null (reload doesn't help)

// Detach the object from the context
((IObjectContextAdapter)northwindEntities).ObjectContext.Detach(newProduct);

// Now find the product by primary key (detached entities are not cached)
var detachedProductByPK = northwindEntities.Products.Find(newProduct.ProductID);
Console.WriteLine(detachedProductByPK.Category); // works (no caching)

Я могу сделать вывод, что реальное обновление/перезагрузка объекта EF может быть выполнено с помощью Detach + Find:

((IObjectContextAdapter)context).ObjectContext.Detach(entity);
entity = context.<SomeEntitySet>.Find(entity.PrimaryKey);

Наков

person Svetlin Nakov    schedule 15.08.2013
comment
От NAA @Dimitar-Dimitrov: You use the constructor of your POCO class to create a new Product object and thus it will not be proxy. You should use the DbSet.Create method in order to get proxy. When you detach the entity from the context and load it from the database with the Find method, Entity Framework will create a proxy for the entity. That's why it works with Detach+Find. However, DbEntityEntry.Reload method will not refresh the relationships of the entity. - person bummi; 27.11.2013
comment
@bummi Спасибо за публикацию этой цитаты. Использование DbSet.Create вместо просто нового ‹Entity› для инициализации моей сущности позволило моим свойствам навигации работать после сохранения изменений и перезагрузки сущности. - person Brent Keller; 22.08.2014
comment
Большое Вам спасибо. Это работает для меня. Перезагрузка не работает ни в том, ни в другом случае, если данные были изменены вне EF. - person user1841243; 24.11.2014
comment
странное поведение: после удаления и повторного добавления дочернего объекта к родительскому... мой обновленный родительский объект теперь имеет 2 дочерних объекта вместо 1... Удаленный дочерний объект по какой-то причине все еще существует. - person user1841243; 24.11.2014
comment
Я попробовал метод «Создать», «Добавить», «Сохранить» и «Обновить», но моя переменная все еще не имела идентификатора базы данных моего нового объекта. Какого черта это так сложно? - person Andy Raddatz; 25.08.2015

Я обнаружил, что перезагрузка не выполняется для прокси-сущностей, у которых есть свойства навигации.

В качестве обходного пути сбросьте текущие значения, а затем перезагрузите их следующим образом:

var entry =_ctx.Entry<Document>(instance);
entry.CurrentValues.SetValues(entry.OriginalValues); 
entry.Reload();
person Matstar    schedule 04.11.2014
comment
Не работает. Отношения не сбрасываются до исходных значений. - person magom001; 20.05.2021