public void Queryable_AsTracking() { // TODO: ZZZ - We have hard time to debug it due to .Value that execute without debug work? TestContext.DeleteAll(x => x.Entity_Basics, TestContext.EffortConnection); TestContext.Insert(x => x.Entity_Basics, 10, TestContext.EffortConnection); using (var ctx = new TestContext(TestContext.EffortConnection)) { // BEFORE var futureValue1 = ctx.Entity_Basics.Where(x => x.ColumnInt < 5).OrderBy(x => x.ColumnInt).FutureValue(); var futureValue2 = ctx.Entity_Basics.Where(x => x.ColumnInt >= 5).OrderBy(x => x.ColumnInt).FutureValue(); // TEST: The batch contains 2 queries Assert.AreEqual(2, QueryFutureManager.AddOrGetBatch(ctx.GetObjectContext()).Queries.Count); var value = futureValue1.Value; // AFTER // TEST: The batch contains 2 queries Assert.AreEqual(0, QueryFutureManager.AddOrGetBatch(ctx.GetObjectContext()).Queries.Count); // TEST: The futureList1 has a value and the first item is returned Assert.IsTrue(futureValue1.HasValue); Assert.AreEqual(0, value.ColumnInt); // TEST: The futureList2 has a value and the first item is returned Assert.IsTrue(futureValue2.HasValue); Assert.AreEqual(5, futureValue2.Value.ColumnInt); // TEST: The first item of both FutureValue has been added Assert.AreEqual(2, ctx.ChangeTracker.Entries().Count()); } }
public void Queryable_AsNoTracking() { TestContext.DeleteAll(x => x.Entity_Basics); TestContext.Insert(x => x.Entity_Basics, 10); using (var ctx = new TestContext()) { // BEFORE var futureValue1 = ctx.Entity_Basics.Where(x => x.ColumnInt < 5).OrderBy(x => x.ColumnInt).AsNoTracking().FutureValue(); var futureValue2 = ctx.Entity_Basics.Where(x => x.ColumnInt >= 5).OrderBy(x => x.ColumnInt).AsNoTracking().FutureValue(); // TEST: The batch contains 2 queries Assert.AreEqual(2, QueryFutureManager.AddOrGetBatch(ctx.GetObjectContext()).Queries.Count); var value = futureValue1.Value; // AFTER // TEST: The batch contains 0 queries Assert.AreEqual(0, QueryFutureManager.AddOrGetBatch(ctx.GetObjectContext()).Queries.Count); // TEST: The futureList1 has a value and the first item is returned Assert.IsTrue(futureValue1.HasValue); Assert.AreEqual(0, value.ColumnInt); // TEST: The futureList2 has a value and the first item is returned Assert.IsTrue(futureValue2.HasValue); Assert.AreEqual(5, futureValue2.Value.ColumnInt); // TEST: No entries has been loaded in the change tracker Assert.AreEqual(0, ctx.ChangeTracker.Entries().Count()); } }
public void DelayedQuery_AsTracking() { TestContext.DeleteAll(x => x.Entity_Basics, TestContext.EffortConnection); TestContext.Insert(x => x.Entity_Basics, 10, TestContext.EffortConnection); using (var ctx = new TestContext(TestContext.EffortConnection)) { // BEFORE var futureValue1 = ctx.Entity_Basics.Where(x => x.ColumnInt < 5).DeferredCount().FutureValue(); var futureValue2 = ctx.Entity_Basics.Where(x => x.ColumnInt >= 5).DeferredCount().FutureValue(); // TEST: The batch contains 2 queries Assert.AreEqual(2, QueryFutureManager.AddOrGetBatch(ctx.GetObjectContext()).Queries.Count); var value = futureValue1.Value; // AFTER // TEST: The batch contains 0 queries Assert.AreEqual(0, QueryFutureManager.AddOrGetBatch(ctx.GetObjectContext()).Queries.Count); // TEST: The futureValue1 has a value and the count equal 5 Assert.IsTrue(futureValue1.HasValue); Assert.AreEqual(5, value); // TEST: The futureValue2 has a value and the count equal 5 Assert.IsTrue(futureValue2.HasValue); Assert.AreEqual(5, futureValue2.Value); // TEST: No entries has been loaded in the change tracker (A value is returned, not an entity) Assert.AreEqual(0, ctx.ChangeTracker.Entries().Count()); } }
/// <summary> /// Defer the execution of the <paramref name="query" /> and batch the query command with other /// future queries. The batch is executed when a future query requires a database round trip. /// </summary> /// <typeparam name="TResult">The type of the query result.</typeparam> /// <param name="query">The query to defer the execution and to add in the batch of future queries.</param> /// <returns> /// The QueryFutureValue<TResult,TResult> added to the batch of futures queries. /// </returns> public static QueryFutureValue <TResult> FutureValue <TResult>(this QueryDeferred <TResult> query) { if (!QueryFutureManager.AllowQueryBatch) { var futureValue = new QueryFutureValue <TResult>(null, null); futureValue.GetResultDirectly(query.Query); return(futureValue); } #if EF5 || EF6 var objectQuery = query.Query.GetObjectQuery(); var futureBatch = QueryFutureManager.AddOrGetBatch(objectQuery.Context); var futureQuery = new QueryFutureValue <TResult>(futureBatch, objectQuery); #elif EFCORE QueryFutureBatch futureBatch; QueryFutureValue <TResult> futureQuery; if (query.Query.IsInMemoryQueryContext()) { var context = query.Query.GetInMemoryContext(); futureBatch = QueryFutureManager.AddOrGetBatch(context); futureBatch.IsInMemory = true; futureQuery = new QueryFutureValue <TResult>(futureBatch, query.Query); futureQuery.InMemoryDeferredQuery = query; } else { var context = query.Query.GetDbContext(); futureBatch = QueryFutureManager.AddOrGetBatch(context); futureQuery = new QueryFutureValue <TResult>(futureBatch, query.Query); } #endif futureBatch.Queries.Add(futureQuery); return(futureQuery); }
public void Queryable_AsTracking() { TestContext.DeleteAll(x => x.Entity_Basics); TestContext.Insert(x => x.Entity_Basics, 10); using (var ctx = new TestContext()) { // BEFORE var futureList1 = ctx.Entity_Basics.Where(x => x.ColumnInt < 5).Future(); var futureList2 = ctx.Entity_Basics.Where(x => x.ColumnInt >= 5).Future(); // TEST: The batch contains 2 queries Assert.AreEqual(2, QueryFutureManager.AddOrGetBatch(ctx.GetObjectContext()).Queries.Count); var list = futureList1.ToList(); // AFTER // TEST: The batch contains 0 queries Assert.AreEqual(0, QueryFutureManager.AddOrGetBatch(ctx.GetObjectContext()).Queries.Count); // TEST: The futureList1 has a value and the list contains 5 items Assert.IsTrue(futureList1.HasValue); Assert.AreEqual(5, futureList1.ToList().Count); Assert.AreEqual(5, list.Count); // TEST: The futureList2 has a value and the list contains 5 items Assert.IsTrue(futureList2.HasValue); Assert.AreEqual(5, futureList2.ToList().Count); // TEST: All entries has been loaded in the change tracker Assert.AreEqual(10, ctx.ChangeTracker.Entries().Count()); } }
/// <summary> /// Defer the execution of the <paramref name="query" /> and batch the query command with other /// future queries. The batch is executed when a future query requires a database round trip. /// </summary> /// <typeparam name="TResult">The type of the query result.</typeparam> /// <param name="query">The query to defer the execution and to add in the batch of future queries.</param> /// <returns> /// The QueryFutureValue<TResult,TResult> added to the batch of futures queries. /// </returns> public static QueryFutureValue <TResult> FutureValue <TResult>(this QueryDeferred <TResult> query) { #if EF5 || EF6 var objectQuery = query.Query.GetObjectQuery(); var futureBatch = QueryFutureManager.AddOrGetBatch(objectQuery.Context); var futureQuery = new QueryFutureValue <TResult>(futureBatch, objectQuery); #elif EF7 var context = query.Query.GetDbContext(); var futureBatch = QueryFutureManager.AddOrGetBatch(context); var futureQuery = new QueryFutureValue <TResult>(futureBatch, query.Query); #endif futureBatch.Queries.Add(futureQuery); return(futureQuery); }
public async Task Queryable_ConcatWithOrderBy_AsNoTracking() { TestContext.DeleteAll(x => x.Entity_Basics); TestContext.Insert(x => x.Entity_Basics, 10); TestContext.DeleteAll(x => x.Entity_Guids); TestContext.Insert(x => x.Entity_Guids, 10); using (var ctx = new TestContext()) { var future1 = ctx.Entity_Basics .Select(eb => eb.ID) .Concat(ctx.Entity_Guids.Select(i => i.ColumnInt).Future()) .OrderBy(x => x) .Future(); var future2 = ctx.Entity_Basics .Select(eb => eb.ID) .Concat(ctx.Entity_Guids.Select(i => i.ColumnInt).Future()) .OrderBy(x => x) .Future(); // DOESN'T WORK with ToListAsync()... due to having 2 queries... we don't care, use the non async var noFutureResult = await ctx.Entity_Basics .Select(eb => eb.ID) .Concat(ctx.Entity_Guids.Select(i => i.ColumnInt).Future()) .OrderBy(x => x) .ToListAsync(); Assert.AreEqual(2, QueryFutureManager.AddOrGetBatch(ctx.GetObjectContext()).Queries.Count); var futureResult1 = await future1.ToListAsync(); var futureResult2 = await future2.ToListAsync(); Assert.AreEqual(0, QueryFutureManager.AddOrGetBatch(ctx.GetObjectContext()).Queries.Count); Assert.IsTrue(future1.HasValue); Assert.IsTrue(future2.HasValue); CollectionAssert.AreEqual(noFutureResult, futureResult1); CollectionAssert.AreEqual(noFutureResult, futureResult2); } }