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