【问题标题】:Check if entity is being tracked by Entity Framework context检查实体框架上下文是否正在跟踪实体
【发布时间】:2015-07-09 03:30:30
【问题描述】:

我有一个代码块,用于检查我的上下文是否正在跟踪实体。如果是,我需要将其分离。这适用于给定的 T 类型。

public virtual async Task<bool> InsertOrUpdate(TE entity)
{
    if (entity.Id == 0 || entity.Id == ModelState.New)
    {
        // attach new entity
        _context.Entry(entity).State = EntityState.Added;
    }
    else
    {
        // Sometimes when you want to update a detached entity, before attempting to attach it (by setting the .State property),
        // you first need to make sure the entity isn't already attached and being tracked. If this is the case, the existing entity
        // needs to be detached, and the updated entity, attached.
        var attachedEntity = _context.ChangeTracker.Entries<TE>().FirstOrDefault(e => e.Entity.Id == entity.Id);
        if (attachedEntity != null)
        {
            // the entity you want to update is already attached, we need to detach it and attach the updated entity instead
            _context.Entry<TE>(attachedEntity.Entity).State = EntityState.Detached;
        }

        _context.Entry<TE>(entity).State = EntityState.Modified; // Attach entity, and set State to Modified.
        _context.Entry<TE>(entity).Property(o => o.CreatedUserId).IsModified = false;
        _context.Entry<TE>(entity).Property(o => o.CreatedDate).IsModified = false;
    }

    return await _context.SaveChangesAsync() > 0;
}

我现在需要更改方法,以便它在给定的 T 实体参数中获取 IEntity 类型的所有对象,然后对找到的每个对象执行相同的逻辑,但是我无法将 ChangeTracker.Entries 设置为 I需要将T类型设置为foreach中当前选择的类型。我不知道该怎么做。

public virtual async Task<bool> InsertOrUpdate(TE entity)
{
    //// Find all instances of IEntity within TE: 
    ////  * IF entity is new we set State to EntityState.Added (INSERT)
    ////  * IF entity is existing, we set State to EntityState.Modified (UPDATE)
    List<IEntity> found = FindAllInstances<IEntity>(entity);
    foreach (IEntity ent in found)
    {
        if (entity.Id == 0 || entity.Id == ModelState.New)
        {
            // attach new entity
            _context.Entry(entity).State = EntityState.Added;
        }
        else
        {
            // Sometimes when you want to update a detached entity, before attempting to attach it (by setting the .State property),
            // you first need to make sure the entity isn't already attached and being tracked. If this is the case, the existing entity
            // needs to be detached, and the updated entity, attached.
            var attachedEntity = _context.ChangeTracker.Entries<TE>().FirstOrDefault(e => e.Entity.Id == entity.Id);
            if (attachedEntity != null)
            {
                // the entity you want to update is already attached, we need to detach it and attach the updated entity instead
                _context.Entry<TE>(attachedEntity.Entity).State = EntityState.Detached;
            }

            _context.Entry<TE>(entity).State = EntityState.Modified; // Attach entity, and set State to Modified.
            _context.Entry<TE>(entity).Property(o => o.CreatedUserId).IsModified = false;
            _context.Entry<TE>(entity).Property(o => o.CreatedDate).IsModified = false;
        }
    }

    return await _context.SaveChangesAsync() > 0;
}

【问题讨论】:

  • 作为旁注,您不能使用_context.Set&lt;TE&gt;().Find(entity.Id) 而不是通过更改跟踪器吗?

标签: c# generics entity-framework-6


【解决方案1】:

你可以使用内部上下文,它是一个 ObjectContext。

var ctx = ((IObjectContextAdapter)_context).ObjectContext;

然后在您想要的任何实体上调用ctx.Detach()。幸运的是,这不是通用方法。

您还可以从ObjectContext 中获取对ObjetStateManager 的引用,并使用它来执行您想要的任何状态更改。

更多信息: https://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.objectstatemanager(v=vs.110).aspx

https://msdn.microsoft.com/en-us/library/system.data.objects.objectstatemanager(v=vs.110).aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-20
    • 2019-03-15
    • 1970-01-01
    • 1970-01-01
    • 2011-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多