I have the following Entity Framework 7 entities:
public class EbookFile {
public Int32 EbookId { get; set; }
public Int32 FileId { get; set; }
public virtual Ebook Ebook { get; set; }
public virtual File File { get; set; }
}
public class File {
public Int32 Id { get; set; }
public Byte[] Content { get; set; }
public String Name { get; set; }
public virtual ICollection<EbookFile> EbooksFiles { get; set; }
}
Given an EbookId I need to get Ids and Names of all files associated with it:
Dictionary<Int32, Dictionary<String, Int32>> files = await _context
.EbooksFiles
.Include(x => x.File)
.Where(x => result.Select(y => y.Id).Contains(x.EbookId))
.GroupBy(x => x.EbookId)
.ToDictionaryAsync(x => x.Key, x => x.ToDictionary(y => y.File.Name, y => y.File.Id));
The problem is that I am also getting the Content which I do not want:
SELECT [x].[EbookId], [x].[FileId], [f].[Id], [f].[Content], [f].[Name]
FROM [EbooksFiles] AS [x]
INNER JOIN [Files] AS [f] ON [x].[FileId] = [f].[Id]
How can I improve my Linq expression to get only the FileId and Name into a dictionary?
TEST QUERY
var ids = new Int32[] { 1, 2 };
var files = _context
.EbooksFiles
.Where(x => ids.Contains(x.EbookId))
.Select(x => new { x.EbookId, x.File.Name, x.File.Id })
.GroupBy(x => x.EbookId)
.ToList();
STACK TRACE
2016-04-29 15:13:40 [Error] An unhandled exception has occurred while executing the request
System.InvalidOperationException: Sequence contains more than one element
at System.Linq.Enumerable.Single[TSource](IEnumerable1 source)
at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.<>c__DisplayClass79_0
1.b__0(IEnumerable1 ps, IQuerySource qs)
at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.BindMemberExpressionCore[TResult](MemberExpression memberExpression, IQuerySource querySource, Func
3 memberBinder)
at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.BindMemberExpression[TResult](MemberExpression memberExpression, IQuerySource querySource, Func3 memberBinder)
at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.BindMemberExpression(MemberExpression memberExpression, Action
2 memberBinder)
at Microsoft.Data.Entity.Query.ExpressionVisitors.Internal.RequiresMaterializationExpressionVisitor.VisitMember(MemberExpression memberExpression)
at System.Linq.Expressions.MemberExpression.Accept(ExpressionVisitor visitor)
at Microsoft.Data.Entity.Query.ExpressionVisitors.ExpressionVisitorBase.Visit(Expression expression)
at System.Linq.Expressions.ExpressionVisitor.VisitAndConvert[T](ReadOnlyCollection1 nodes, String callerName)
at Remotion.Linq.Parsing.RelinqExpressionVisitor.VisitNew(NewExpression expression)
at System.Linq.Expressions.NewExpression.Accept(ExpressionVisitor visitor)
at Microsoft.Data.Entity.Query.ExpressionVisitors.ExpressionVisitorBase.Visit(Expression expression)
at Remotion.Linq.Clauses.ResultOperators.GroupResultOperator.TransformExpressions(Func
2 transformation)
at Remotion.Linq.QueryModel.TransformExpressions(Func2 transformation)
at Microsoft.Data.Entity.Query.ExpressionVisitors.Internal.RequiresMaterializationExpressionVisitor.FindQuerySourcesRequiringMaterialization(QueryModel queryModel)
at Microsoft.Data.Entity.Query.QueryCompilationContext.FindQuerySourcesRequiringMaterialization(EntityQueryModelVisitor queryModelVisitor, QueryModel queryModel)
at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.CreateQueryExecutor[TResult](QueryModel queryModel)
at Microsoft.Data.Entity.Storage.Database.CompileQuery[TResult](QueryModel queryModel)
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.Data.Entity.Query.Internal.QueryCompiler.<>c__DisplayClass18_0
1.b__0()
at Microsoft.Data.Entity.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func1 compiler)
at Microsoft.Data.Entity.Query.Internal.QueryCompiler.CompileQuery[TResult](Expression query)
at Microsoft.Data.Entity.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Microsoft.Data.Entity.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
at Remotion.Linq.QueryableBase
1.GetEnumerator()
at System.Collections.Generic.List1..ctor(IEnumerable
1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source)
at EbookGetApiModelHandler.QueryHandler.<Handle>d__4.MoveNext() in \Handlers\EbookGetApiModelHandler.cs:line 85
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MediatR.Mediator.<SendAsync>d__4
1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter1.GetResult()
at Controllers.EbookApiController.<Get>d__2.MoveNext() in \Controllers\EbookApiController.cs:line 30
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Mvc.Controllers.ControllerActionExecutor.<CastToObject>d__8
1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Mvc.Controllers.ControllerActionInvoker.d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.d__53.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.d__44.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Mvc.Infrastructure.MvcRouteHandler.d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Mvc.Routing.InnerAttributeRoute.d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Routing.RouteCollection.d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Builder.RouterMiddleware.d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Authentication.AuthenticationMiddleware1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNet.Authentication.AuthenticationMiddleware
1.d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Authentication.AuthenticationMiddleware1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNet.Authentication.AuthenticationMiddleware
1.d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Authentication.AuthenticationMiddleware1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNet.Authentication.AuthenticationMiddleware
1.d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Authentication.AuthenticationMiddleware1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNet.Authentication.AuthenticationMiddleware
1.d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Localization.RequestLocalizationMiddleware.d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Diagnostics.Entity.MigrationsEndPointMiddleware.d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Diagnostics.Entity.DatabaseErrorPageMiddleware.d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNet.Diagnostics.Entity.DatabaseErrorPageMiddleware.d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Diagnostics.DeveloperExceptionPageMiddleware.d__7.MoveNext()