From a293cd6190163fefc6672b6bc801879d4a173e2f Mon Sep 17 00:00:00 2001 From: Israel lot Date: Tue, 14 Oct 2014 00:51:45 -0300 Subject: [PATCH 1/2] FutureQueries async --- .../Extensions/FutureExtensions.cs | 8 +++---- .../Future/FutureContext.cs | 17 +++++++++++++++ .../Future/FutureCount.cs | 3 ++- .../Future/FutureQuery.cs | 14 +++++++++++-- .../Future/FutureQueryBase.cs | 11 +++++----- .../Future/FutureRunner.cs | 21 +++++++++++++++++-- .../Future/FutureValue.cs | 11 ++++++++-- .../Future/IFutureContext.cs | 6 ++++++ .../Future/IFutureRunner.cs | 8 +++++++ 9 files changed, 83 insertions(+), 16 deletions(-) diff --git a/Source/EntityFramework.Extended/Extensions/FutureExtensions.cs b/Source/EntityFramework.Extended/Extensions/FutureExtensions.cs index 8b18a97..2102df1 100644 --- a/Source/EntityFramework.Extended/Extensions/FutureExtensions.cs +++ b/Source/EntityFramework.Extended/Extensions/FutureExtensions.cs @@ -33,7 +33,7 @@ public static FutureQuery Future(this IQueryable sour throw new ArgumentException("The source query must be of type ObjectQuery or DbQuery.", "source"); var futureContext = GetFutureContext(sourceQuery); - var future = new FutureQuery(sourceQuery, futureContext.ExecuteFutureQueries); + var future = new FutureQuery(sourceQuery, futureContext.ExecuteFutureQueriesAsync); futureContext.AddQuery(future); return future; @@ -69,7 +69,7 @@ public static FutureCount FutureCount(this IQueryable source) throw new ArgumentException("The source query must be of type ObjectQuery or DbQuery.", "source"); var futureContext = GetFutureContext(sourceQuery); - var future = new FutureCount(countQuery, futureContext.ExecuteFutureQueries); + var future = new FutureCount(countQuery, futureContext.ExecuteFutureQueriesAsync); futureContext.AddQuery(future); return future; } @@ -111,7 +111,7 @@ public static FutureValue FutureValue(this IQueryable throw new ArgumentException("The source query must be of type ObjectQuery or DbQuery.", "source"); var futureContext = GetFutureContext(sourceQuery); - var future = new FutureValue(valueQuery, futureContext.ExecuteFutureQueries); + var future = new FutureValue(valueQuery, futureContext.ExecuteFutureQueriesAsync); futureContext.AddQuery(future); return future; } @@ -141,7 +141,7 @@ public static FutureValue FutureFirstOrDefault(this IQueryable throw new ArgumentException("The source query must be of type ObjectQuery or DbQuery.", "source"); var futureContext = GetFutureContext(sourceQuery); - var future = new FutureValue(objectQuery, futureContext.ExecuteFutureQueries); + var future = new FutureValue(objectQuery, futureContext.ExecuteFutureQueriesAsync); futureContext.AddQuery(future); return future; } diff --git a/Source/EntityFramework.Extended/Future/FutureContext.cs b/Source/EntityFramework.Extended/Future/FutureContext.cs index 8a57bea..73806f6 100644 --- a/Source/EntityFramework.Extended/Future/FutureContext.cs +++ b/Source/EntityFramework.Extended/Future/FutureContext.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Data.Entity.Core.Objects; +using System.Threading.Tasks; namespace EntityFramework.Future { @@ -85,6 +86,22 @@ public void ExecuteFutureQueries() runner.ExecuteFutureQueries(context, FutureQueries); } + /// + /// Executes the future queries as a single batch. + /// + public async Task ExecuteFutureQueriesAsync() + { + ObjectContext context = ObjectContext; + if (context == null) + throw new ObjectDisposedException("ObjectContext", "The ObjectContext for the future queries has been displosed."); + + var runner = Locator.Current.Resolve(); + if (runner == null) + throw new InvalidOperationException("Could not resolve the IFutureRunner. Make sure IFutureRunner is registered in the Locator.Current container."); + + await runner.ExecuteFutureQueriesAsync(context, FutureQueries); + } + /// /// Adds the future query to the waiting queries list on this context. /// diff --git a/Source/EntityFramework.Extended/Future/FutureCount.cs b/Source/EntityFramework.Extended/Future/FutureCount.cs index 6dad9e4..39c86a5 100644 --- a/Source/EntityFramework.Extended/Future/FutureCount.cs +++ b/Source/EntityFramework.Extended/Future/FutureCount.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics; using System.Linq; +using System.Threading.Tasks; namespace EntityFramework.Future { @@ -31,7 +32,7 @@ public class FutureCount : FutureValue /// /// The query source to use when materializing. /// The action to execute when the query is accessed. - internal FutureCount(IQueryable query, Action loadAction) + internal FutureCount(IQueryable query, Func loadAction) : base(query, loadAction) { } diff --git a/Source/EntityFramework.Extended/Future/FutureQuery.cs b/Source/EntityFramework.Extended/Future/FutureQuery.cs index bf7b797..a7095e0 100644 --- a/Source/EntityFramework.Extended/Future/FutureQuery.cs +++ b/Source/EntityFramework.Extended/Future/FutureQuery.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Threading.Tasks; namespace EntityFramework.Future { @@ -30,7 +31,7 @@ public class FutureQuery : FutureQueryBase, IEnumerable /// /// The query source to use when materializing. /// The action to execute when the query is accessed. - internal FutureQuery(IQueryable query, Action loadAction) + internal FutureQuery(IQueryable query, Func loadAction) : base(query, loadAction) { } @@ -43,7 +44,7 @@ internal FutureQuery(IQueryable query, Action loadAction) public IEnumerator GetEnumerator() { // triggers loading future queries - var result = GetResult() ?? Enumerable.Empty(); + var result = GetResultAsync().Result?? Enumerable.Empty(); if (Exception != null) throw new FutureException("An error occurred executing the future query.", Exception); @@ -51,6 +52,15 @@ public IEnumerator GetEnumerator() return result.GetEnumerator(); } + public async Task> ToListAsync() + { + var result = await GetResultAsync(); + + return result.ToList(); + + } + + /// /// Returns an enumerator that iterates through a collection. /// diff --git a/Source/EntityFramework.Extended/Future/FutureQueryBase.cs b/Source/EntityFramework.Extended/Future/FutureQueryBase.cs index fafc15f..7eedc94 100644 --- a/Source/EntityFramework.Extended/Future/FutureQueryBase.cs +++ b/Source/EntityFramework.Extended/Future/FutureQueryBase.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Linq; using EntityFramework.Reflection; +using System.Threading.Tasks; namespace EntityFramework.Future { @@ -15,7 +16,7 @@ namespace EntityFramework.Future [DebuggerDisplay("IsLoaded={IsLoaded}")] public abstract class FutureQueryBase : IFutureQuery { - private readonly Action _loadAction; + private readonly Func _loadAction; private readonly IQueryable _query; private IEnumerable _result; private bool _isLoaded; @@ -25,7 +26,7 @@ public abstract class FutureQueryBase : IFutureQuery /// /// The query source to use when materializing. /// The action to execute when the query is accessed. - protected FutureQueryBase(IQueryable query, Action loadAction) + protected FutureQueryBase(IQueryable query, Func loadAction) { _query = query; _loadAction = loadAction; @@ -36,7 +37,7 @@ protected FutureQueryBase(IQueryable query, Action loadAction) /// Gets the action to execute when the query is accessed. /// /// The load action. - protected Action LoadAction + protected Func LoadAction { get { return _loadAction; } } @@ -71,7 +72,7 @@ IQueryable IFutureQuery.Query /// /// An that can be used to iterate through the collection. /// - protected virtual IEnumerable GetResult() + protected virtual async Task> GetResultAsync() { if (IsLoaded) return _result; @@ -86,7 +87,7 @@ protected virtual IEnumerable GetResult() // invoke the load action on the datacontext // result will be set with a callback to SetResult - LoadAction.Invoke(); + await LoadAction.Invoke(); return _result ?? Enumerable.Empty(); } diff --git a/Source/EntityFramework.Extended/Future/FutureRunner.cs b/Source/EntityFramework.Extended/Future/FutureRunner.cs index f8027de..0b74a51 100644 --- a/Source/EntityFramework.Extended/Future/FutureRunner.cs +++ b/Source/EntityFramework.Extended/Future/FutureRunner.cs @@ -5,6 +5,8 @@ using System.Data.Entity.Core.Objects; using System.Text; using EntityFramework.Reflection; +using System.Threading.Tasks; +using System.Diagnostics; namespace EntityFramework.Future { @@ -13,12 +15,13 @@ namespace EntityFramework.Future /// public class FutureRunner : IFutureRunner { + /// /// Executes the future queries. /// /// The to run the queries against. /// The future queries list. - public void ExecuteFutureQueries(ObjectContext context, IList futureQueries) + public async Task ExecuteFutureQueriesAsync(ObjectContext context, IList futureQueries) { if (context == null) throw new ArgumentNullException("context"); @@ -31,9 +34,20 @@ public void ExecuteFutureQueries(ObjectContext context, IList futu try { +#if DEBUG + System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); + sw.Start(); +#endif using (var command = CreateFutureCommand(context, futureQueries)) - using (var reader = command.ExecuteReader()) + using (var reader = await command.ExecuteReaderAsync()) { +#if DEBUG + Debug.WriteLine("Executing Query: "); + Debug.WriteLine(command.CommandText); + Debug.WriteLine("Time Elapsed: " + sw.ElapsedMilliseconds.ToString("f2") + "ms"); + +#endif + foreach (var futureQuery in futureQueries) { futureQuery.SetResult(context, reader); @@ -110,5 +124,8 @@ private static DbCommand CreateFutureCommand(ObjectContext context, IEnumerable< return command; } + + + } } \ No newline at end of file diff --git a/Source/EntityFramework.Extended/Future/FutureValue.cs b/Source/EntityFramework.Extended/Future/FutureValue.cs index 4e283b2..cb03f0f 100644 --- a/Source/EntityFramework.Extended/Future/FutureValue.cs +++ b/Source/EntityFramework.Extended/Future/FutureValue.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics; using System.Linq; +using System.Threading.Tasks; namespace EntityFramework.Future { @@ -30,7 +31,7 @@ public class FutureValue : FutureQueryBase /// /// The query source to use when materializing. /// The action to execute when the query is accessed. - internal FutureValue(IQueryable query, Action loadAction) + internal FutureValue(IQueryable query, Func loadAction) : base(query, loadAction) { } @@ -60,7 +61,7 @@ public T Value { _hasValue = true; - var result = GetResult() ?? Enumerable.Empty(); + var result = GetResultAsync().Result ?? Enumerable.Empty(); UnderlyingValue = result.FirstOrDefault(); } @@ -76,6 +77,12 @@ public T Value } } + public async Task ValueAsync() + { + return (await GetResultAsync()).FirstOrDefault(); + } + + /// /// Performs an implicit conversion from to T. /// diff --git a/Source/EntityFramework.Extended/Future/IFutureContext.cs b/Source/EntityFramework.Extended/Future/IFutureContext.cs index 165f50a..d35b78c 100644 --- a/Source/EntityFramework.Extended/Future/IFutureContext.cs +++ b/Source/EntityFramework.Extended/Future/IFutureContext.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; namespace EntityFramework.Future { @@ -19,6 +20,11 @@ public interface IFutureContext /// void ExecuteFutureQueries(); + /// + /// Executes the future queries. + /// + Task ExecuteFutureQueriesAsync(); + /// /// Adds the future query to the waiting queries list on this context. /// diff --git a/Source/EntityFramework.Extended/Future/IFutureRunner.cs b/Source/EntityFramework.Extended/Future/IFutureRunner.cs index dc303f0..5524af2 100644 --- a/Source/EntityFramework.Extended/Future/IFutureRunner.cs +++ b/Source/EntityFramework.Extended/Future/IFutureRunner.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Data.Entity.Core.Objects; +using System.Threading.Tasks; namespace EntityFramework.Future { @@ -15,5 +16,12 @@ public interface IFutureRunner /// The to run the queries against. /// The future queries list. void ExecuteFutureQueries(ObjectContext context, IList futureQueries); + + /// + /// Executes the future queries. + /// + /// The to run the queries against. + /// The future queries list. + Task ExecuteFutureQueriesAsync(ObjectContext context, IList futureQueries); } } \ No newline at end of file From 182916270221700f60ff8efc239c16769cad4494 Mon Sep 17 00:00:00 2001 From: Israel lot Date: Tue, 14 Oct 2014 10:24:15 -0300 Subject: [PATCH 2/2] Future Queries Async --- .../Future/FutureContext.cs | 16 +--------------- .../Future/IFutureContext.cs | 5 +---- .../Future/IFutureRunner.cs | 7 +------ 3 files changed, 3 insertions(+), 25 deletions(-) diff --git a/Source/EntityFramework.Extended/Future/FutureContext.cs b/Source/EntityFramework.Extended/Future/FutureContext.cs index 73806f6..cd32e35 100644 --- a/Source/EntityFramework.Extended/Future/FutureContext.cs +++ b/Source/EntityFramework.Extended/Future/FutureContext.cs @@ -70,21 +70,7 @@ public bool IsAlive get { return _objectContext.IsAlive; } } - /// - /// Executes the future queries as a single batch. - /// - public void ExecuteFutureQueries() - { - ObjectContext context = ObjectContext; - if (context == null) - throw new ObjectDisposedException("ObjectContext", "The ObjectContext for the future queries has been displosed."); - - var runner = Locator.Current.Resolve(); - if (runner == null) - throw new InvalidOperationException("Could not resolve the IFutureRunner. Make sure IFutureRunner is registered in the Locator.Current container."); - - runner.ExecuteFutureQueries(context, FutureQueries); - } + /// /// Executes the future queries as a single batch. diff --git a/Source/EntityFramework.Extended/Future/IFutureContext.cs b/Source/EntityFramework.Extended/Future/IFutureContext.cs index d35b78c..d912335 100644 --- a/Source/EntityFramework.Extended/Future/IFutureContext.cs +++ b/Source/EntityFramework.Extended/Future/IFutureContext.cs @@ -15,10 +15,7 @@ public interface IFutureContext /// The future queries. IList FutureQueries { get; } - /// - /// Executes the future queries. - /// - void ExecuteFutureQueries(); + /// /// Executes the future queries. diff --git a/Source/EntityFramework.Extended/Future/IFutureRunner.cs b/Source/EntityFramework.Extended/Future/IFutureRunner.cs index 5524af2..979c7f3 100644 --- a/Source/EntityFramework.Extended/Future/IFutureRunner.cs +++ b/Source/EntityFramework.Extended/Future/IFutureRunner.cs @@ -10,12 +10,7 @@ namespace EntityFramework.Future /// public interface IFutureRunner { - /// - /// Executes the future queries. - /// - /// The to run the queries against. - /// The future queries list. - void ExecuteFutureQueries(ObjectContext context, IList futureQueries); + /// /// Executes the future queries.