Test "TestThenIncludeSortSingle" is faling
Juansero29 opened this issue · comments
I just cloned the repo and the first thing I did was executing all test. There is a single test failing called "TestThenIncludeSortSingle".
Here's the exception it is throwing:
Message:
System.InvalidOperationException : The expression 'bookAuthor.AsQueryable().OrderBy(y => y.Author.Name)' is invalid inside an 'Include' operation, since it does not represent a property access: 't => t.MyProperty'. To target navigations declared on derived types, use casting ('t => ((Derived)t).MyProperty') or the 'as' operator ('t => (t as Derived).MyProperty'). Collection navigation access can be filtered by composing Where, OrderBy(Descending), ThenBy(Descending), Skip or Take operations. For more information on including related data, see http://go.microsoft.com/fwlink/?LinkID=746393.
Stack Trace:
NavigationExpandingExpressionVisitor.<ProcessInclude>g__ExtractIncludeFilter|31_0(Expression currentExpression, Expression includeExpression)
NavigationExpandingExpressionVisitor.<ProcessInclude>g__ExtractIncludeFilter|31_0(Expression currentExpression, Expression includeExpression)
NavigationExpandingExpressionVisitor.<ProcessInclude>g__ExtractIncludeFilter|31_0(Expression currentExpression, Expression includeExpression)
NavigationExpandingExpressionVisitor.ProcessInclude(NavigationExpansionExpression source, Expression expression, Boolean thenInclude)
NavigationExpandingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
MethodCallExpression.Accept(ExpressionVisitor visitor)
ExpressionVisitor.Visit(Expression node)
NavigationExpandingExpressionVisitor.Expand(Expression query)
QueryTranslationPreprocessor.Process(Expression query)
RelationalQueryTranslationPreprocessor.Process(Expression query)
QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
Database.CompileQuery[TResult](Expression query, Boolean async)
QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
<>c__DisplayClass9_0`1.<Execute>b__0()
CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
QueryCompiler.Execute[TResult](Expression query)
EntityQueryProvider.Execute[TResult](Expression expression)
EntityQueryable`1.GetEnumerator()
IncludableQueryable`2.GetEnumerator()
List`1.ctor(IEnumerable`1 collection)
Enumerable.ToList[TSource](IEnumerable`1 source)
Ch02_IncludeSortFilter.TestThenIncludeSortSingle() line 207
And here's the original code of this test:
[Fact]
public void TestThenIncludeSortSingle()
{
//SETUP
var options = SqliteInMemory.CreateOptions<EfCoreContext>();
using var context = new EfCoreContext(options);
context.Database.EnsureCreated();
var newBook = new Book
{
AuthorsLink = new List<BookAuthor>
{
new BookAuthor {Author = new Author {Name = "Author2"}, Order = 2},
new BookAuthor {Author = new Author {Name = "Author1"}, Order = 1},
}
};
context.Add(newBook);
context.SaveChanges();
//ATTEMPT
var query = context.Books
.Include(book => book.AuthorsLink)//.OrderBy(y => y.Order))
.ThenInclude(bookAuthor => bookAuthor.OrderBy(y => y.Author.Name));
var books = query.ToList();
//VERIFY
_output.WriteLine(query.ToQueryString());
books.Single().AuthorsLink.Select(x => x.Author.Name).ShouldEqual(new[] { "Author1", "Author2" });
}
It would seem like it is impossible for EF to do an OrderBy()
inside the ThenInclude(x => [...])
lambda. How can we make this test repass correctly?
Hi @Juansero29,
Yes, I know this unit test fails. I thought would work but it doesn't and I haven't found a way to do get it to work. Therefore I left it as a failing unit test because it points out that there are limitations on this new feature
Hello @JonPSmith,
I just ran into this myself. I believe that since this test is now existing to showcase a limitation, that the test should be adjusted to verify this limitation instead of having broken unit tests on a fresh clone. I was left wondering for a bit if my local system had some difference that was making it fail, and Google wasn't helping. Then I found this Issue and all was made clear.
But to document this intention in the code, the test could be changed to something like the following:
[Fact]
public void TestThenIncludeSortSingle()
{
//SETUP
// ...No changes to Setup...
//ATTEMPT
var query = context.Books
.Include(book => book.AuthorsLink) //.OrderBy(y => y.Order))
.ThenInclude(bookAuthor => bookAuthor.OrderBy(y => y.Author.Name));
void ExecuteQueryAction() => query.ToList();
//VERIFY
// Could not get this to work due to limitations on this new feature. See https://github.com/JonPSmith/EfCoreinAction-SecondEdition/issues/7
// The expression 'bookAuthor.AsQueryable().OrderBy(y => y.Author.Name)' is invalid inside an 'Include' operation, since it does not represent a property access: 't => t.MyProperty'.
Assert.Throws<InvalidOperationException>(ExecuteQueryAction);
}
Alternatively, the test could be skipped with an explanation:
[Fact(Skip = "Could not get this to work due to limitations on this new feature. See https://github.com/JonPSmith/EfCoreinAction-SecondEdition/issues/7")]
I believe this would be a better experience for those expecting a fresh clone / checkout of master
to work out of the box.
Thanks!
P.S.
Just by cracking open this solution I learned about ToQueryString()
and ITestOutputHelper
, two very useful things. Also, the book's been a good read so far (just got into part 2).