what is the most reasonable way to find out if entity is attached to dbContext or not?

Solution 1:

If you are using DbContext API (you mentioned ef-code-first) you can simply use:

context.YourEntities.Local.Any(e => e.Id == id);

or more complex

context.ChangeTracker.Entries<YourEntity>().Any(e => e.Entity.Id == id);

In case of ObjectContext API you can use:

context.ObjectStateManager.GetObjectStateEntries(~EntityState.Detached)
                          .Where(e => !e.IsRelationship)
                          .Select(e => e.Entity)
                          .OfType<YourEntity>()
                          .Any(x => x.Id == id);

Solution 2:

Here's an extension method for getting the object from the context without having to worry about whether it is already attached:

public static T GetLocalOrAttach<T>(this DbSet<T> collection, Func<T, bool> searchLocalQuery, Func<T> getAttachItem) where T : class
{
    T localEntity = collection.Local.FirstOrDefault(searchLocalQuery);

    if (localEntity == null)
    {
        localEntity = getAttachItem();
        collection.Attach(localEntity);
    }

    return localEntity;
}

Just call:

UserProfile user = dbContext.UserProfiles.GetLocalOrAttach<UserProfile>(u => u.UserId == userId, () => new UserProfile { UserId = userId });

Solution 3:

check

entity.EntityState == System.Data.EntityState.Detached

before attaching