Возможно проверить, присоединен ли объект уже к контексту данных в Платформе Объекта?

Существует хорошая статья здесь об объединении простого синтаксического анализатора с рекурсивным спуском с синтаксическим анализом по грамматике предшествования оператора. Если Вы недавно писали синтаксические анализаторы, это должно быть очень интересно и поучительно для чтения.

83
задан Community 23 May 2017 в 11:47
поделиться

3 ответа

Вот то, что у меня получилось, и это очень хорошо работает:

public static void AttachToOrGet<T>(this ObjectContext context, string entitySetName, ref T entity)
    where T : IEntityWithKey
{
    ObjectStateEntry entry;
    // Track whether we need to perform an attach
    bool attach = false;
    if (
        context.ObjectStateManager.TryGetObjectStateEntry
            (
                context.CreateEntityKey(entitySetName, entity),
                out entry
            )
        )
    {
        // Re-attach if necessary
        attach = entry.State == EntityState.Detached;
        // Get the discovered entity to the ref
        entity = (T)entry.Entity;
    }
    else
    {
        // Attach for the first time
        attach = true;
    }
    if (attach)
        context.AttachTo(entitySetName, entity);
}

Вы можете назвать это следующим образом:

User user = new User() { Id = 1 };
II.AttachToOrGet<Users>("Users", ref user);

Это работает очень хорошо, потому что это похоже на context.AttachTo (...) за исключением того, что вы можете каждый раз использовать трюк с идентификатором, который я цитировал выше. В итоге вы получаете либо прикрепленный ранее объект, либо прикрепленный ваш собственный объект. Вызов CreateEntityKey в контексте гарантирует, что он будет красивым и универсальным и будет работать даже с составными ключами без дальнейшего кодирования (потому что EF уже может сделать это за нас!).

56
ответ дан 24 November 2019 в 08:54
поделиться

Попробуйте этот метод расширения (это непроверено и нестандартно):

public static bool IsAttachedTo(this ObjectContext context, object entity) {
    if(entity == null) {
        throw new ArgumentNullException("entity");
    }
    ObjectStateEntry entry;
    if(context.ObjectStateManager.TryGetObjectStateEntry(entity, out entry)) {
        return (entry.State != EntityState.Detached);
    }
    return false;
}

Учитывая ситуацию, которую вы описываете в своей редакции, вам может потребоваться следующая перегрузка, которая принимает EntityKey вместо объекта:

public static bool IsAttachedTo(this ObjectContext, EntityKey key) {
    if(key == null) {
        throw new ArgumentNullException("key");
    }
    ObjectStateEntry entry;
    if(context.ObjectStateManager.TryGetObjectStateEntry(key, out entry)) {
        return (entry.State != EntityState.Detached);
    }
    return false;
}

Чтобы создать EntityKey в вашей ситуации, используйте следующее в качестве руководства:

EntityKey key = new EntityKey("MyEntities.User", "Id", 1);

Вы можете получить EntityKey из существующего экземпляра пользователя с помощью свойства User.EntityKey (из интерфейса IEntityWithKey ).

18
ответ дан 24 November 2019 в 08:54
поделиться

Использование ключа сущности объекта, который вы пытаетесь проверить:

var entry = context.ObjectStateManager.GetObjectStateEntry("EntityKey");
if (entry.State == EntityState.Detached)
{
  // Do Something
}

Доброта,

Дэн

6
ответ дан 24 November 2019 в 08:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: