Hi,
In my Repositories, I have many Root Entities which load few RelatedEntityList. Right now I am overriding the GetKeyQuery and add many include to my base query. In some case this is becoming an issue as the query aggregate a LOT of data since all is done in one query. Instead of using Includes, I would like to be able to execute some queries in order to load subproperties faster, and avoid EF generating a huge single SQL query with hundreds of fields.
Could it be possible to have this feature in cocktail ?
I had the same issue in one of my search repository and I did it like this :
public class VirtualSearchRepository<TResult> : IVirtualSearchRepository<TResult> where TResult : class {
protected virtual IEntityQuery<TResult> DefineQuery() { return null; } protected virtual Task<IEntityQuery<TResult>> DefineQueryAsync() { var tcs = new TaskCompletionSource<IEntityQuery<TResult>>(); tcs.SetResult(DefineQuery());
return tcs.Task; }
public async Task<IEnumerable<TResult>> AllAsync(Action<TQueryOptions> queryOptions = null, Func<IQueryable<TResult>, IOrderedQueryable<TResult>> orderBy = null, Action<IFetchOptions<TResult>> fetchOptions = null) { ... var qry = await DefineQueryAsync(); ...
return await qry.ExecuteAsync(); } }
that way, If I override the method "IEntityQuery<TResult> DefineQuery()" I am in the exact same situation as with cocktail, I define my query and can add few include if this solution is fast enought for me. But if having multiple query is faster, I just have to override the other method "Task<IEntityQuery<TResult>> DefineQueryAsync()"
exemple :
private async Task<Customer> GetCustomer(int keyValue) { var taskCustomer = new EntityKey(typeof(Customer), keyValue).ToQuery().With(manager).ExecuteAsync(); var taskOrders = new EntityQuery<Order>().With(manager) .Where(p => p.Customer_Id == keyValue) .ExecuteAsync();
await TaskEx.WhenAll(taskCustomer, taskOrders);
return (Customer)taskCustomer.Result.Cast<object>().ToList().First(); }
In my UnitOfWork I have to add this to not have the RelatedEntityList in the Pending mode:
Manager.MetadataStore.GetEntityMetadata(typeof(Customer)) .NavigationProperties.First(p => p.Name.Equals(customer.EntityPropertyNames.Orders)) .ReferenceStrategy = EntityReferenceStrategy.NoLoad;
If you think that this feature has nothing to do in Cocktail's code, could you at least define the following method as virtual in the Repository ? public Task<T> WithIdAsync(object[] keyValues, CancellationToken cancellationToken)
regards
|