/// <summary> /// Finds an entity with the given id. If an entity with the given id /// is being tracked by the context, then it is returned immediately without making a request to the /// database. Otherwise, a query is made to the database for an entity with the given id /// and this entity, if found, is returned. If no entity is found, then /// null is returned. If <paramref name="tracked"/> is <see langword="true"/>, /// then the entity is also attached to the context, so that subsequent calls can /// return the tracked entity without a database roundtrip. /// </summary> /// <param name="id">The primary id of the entity.</param> /// <param name="tracked"> /// Whether to put entity to change tracker after it was loaded from database. Note that <c>false</c> /// has no effect if the entity was in change tracker already (it will NOT be detached). /// </param> /// <returns>The entity found, or null.</returns> /// <remarks> /// This method is slightly faster than <see cref="DbSet{TEntity}.Find(object[])"/> /// because the key is known. /// </remarks> public static TEntity FindById <TEntity, TProperty>(this IIncludableQueryable <TEntity, TProperty> query, int id, bool tracked = true) where TEntity : BaseEntity { if (id == 0) { return(null); } return(query.GetDbContext().FindTracked <TEntity>(id) ?? query.ApplyTracking(tracked).SingleOrDefault(x => x.Id == id)); }
/// <summary> /// Finds an entity with the given id. If an entity with the given id /// is being tracked by the context, then it is returned immediately without making a request to the /// database. Otherwise, a query is made to the database for an entity with the given id /// and this entity, if found, is returned. If no entity is found, then /// null is returned. If <paramref name="tracked"/> is <see langword="true"/>, /// then the entity is also attached to the context, so that subsequent calls can /// return the tracked entity without a database roundtrip. /// </summary> /// <param name="id">The primary id of the entity.</param> /// <param name="tracked"> /// Whether to put entity to change tracker after it was loaded from database. Note that <c>false</c> /// has no effect if the entity was in change tracker already (it will NOT be detached). /// </param> /// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param> /// <returns>The entity found, or null.</returns> /// <remarks> /// This method is slightly faster than <see cref="DbSet{TEntity}.FindAsync(object[], CancellationToken)(object[])"/> /// because the key is known. /// </remarks> public static ValueTask <TEntity> FindByIdAsync <TEntity, TProperty>(this IIncludableQueryable <TEntity, TProperty> query, int id, bool tracked = true, CancellationToken cancellationToken = default) where TEntity : BaseEntity { if (id == 0) { return(ValueTask.FromResult((TEntity)null)); } var trackedEntity = query.GetDbContext().FindTracked <TEntity>(id); return(trackedEntity != null ? new ValueTask <TEntity>(trackedEntity) : new ValueTask <TEntity>( query.ApplyTracking(tracked).SingleOrDefaultAsync(x => x.Id == id, cancellationToken))); }