在关系

时间:2016-04-29 13:35:51

标签: entity-framework linq entity-framework-core

我有以下Entity Framework 7实体:

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; }
}

鉴于EbookId,我需要获取与之关联的所有文件的ID和名称:

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));

问题是我也得到了我不想要的内容:

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]

如何改进我的Linq表达式,只将FileId和Name放入字典?

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 [错误]执行请求时发生了未处理的异常 System.InvalidOperationException:Sequence包含多个元素    在System.Linq.Enumerable.Single [TSource](IEnumerable 1 source) at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.<>c__DisplayClass79_0 1.b__0(IEnumerable 1 ps, IQuerySource qs) at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.BindMemberExpressionCore[TResult](MemberExpression memberExpression, IQuerySource querySource, Func 3 memberBinder)    在Microsoft.Data.Entity.Query.EntityQueryModelVisitor.BindMemberExpression [TResult](MemberExpression memberExpression,IQuerySource querySource,Func 3 memberBinder) at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.BindMemberExpression(MemberExpression memberExpression, Action 2 memberBinder)    at Microsoft.Data.Entity.Query.ExpressionVisitors.Internal.RequiresMaterializationExpressionVisitor.VisitMember(MemberExpression memberExpression)    在System.Linq.Expressions.MemberExpression.Accept(ExpressionVisitor visitor)    at Microsoft.Data.Entity.Query.ExpressionVisitors.ExpressionVisitorBase.Visit(Expression expression)    在System.Linq.Expressions.ExpressionVisitor.VisitAndConvert [T](ReadOnlyCollection 1 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转换)    在Remotion.Linq.QueryModel.TransformExpressions(Func 2 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()    在Microsoft.Data.Entity.Query.Internal.CompiledQueryCache.GetOrAddQuery [TResult](Object cacheKey,Func 1 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()    在System.Collections.Generic.List 1..ctor(IEnumerable 1个集合)    at System.Linq.Enumerable.ToList [TSource](IEnumerable 1 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() ---从抛出异常的先前位置开始的堆栈跟踪结束---    在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)    在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)    在System.Runtime.CompilerServices.TaskAwaiter 1.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() ---从抛出异常的先前位置开始的堆栈跟踪结束---    在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)    在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)    在Microsoft.AspNet.Mvc.Controllers.ControllerActionInvoker.d__6.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束---    在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)    在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)    在System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(任务任务)    在Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.d__53.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束---    在Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.d__44.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束---    在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)    在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)    在Microsoft.AspNet.Mvc.Infrastructure.MvcRouteHandler.d__6.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束---    在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)    在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)    在Microsoft.AspNet.Mvc.Routing.InnerAttributeRoute.d__10.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束---    在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)    在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)    在Microsoft.AspNet.Routing.RouteCollection.d__9.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束---    在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)    在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)    在Microsoft.AspNet.Builder.RouterMiddleware.d__4.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束---    在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)    在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)    在Microsoft.AspNet.Authentication.AuthenticationMiddleware 1.<Invoke>d__18.MoveNext() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNet.Authentication.AuthenticationMiddleware 1.d__18.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束---    在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)    在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)    在Microsoft.AspNet.Authentication.AuthenticationMiddleware 1.<Invoke>d__18.MoveNext() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNet.Authentication.AuthenticationMiddleware 1.d__18.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束---    在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)    在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)    在Microsoft.AspNet.Authentication.AuthenticationMiddleware 1.<Invoke>d__18.MoveNext() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNet.Authentication.AuthenticationMiddleware 1.d__18.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束---    在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)    在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)    在Microsoft.AspNet.Authentication.AuthenticationMiddleware 1.<Invoke>d__18.MoveNext() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNet.Authentication.AuthenticationMiddleware 1.d__18.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束---    在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)    在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)    在Microsoft.AspNet.Localization.RequestLocalizationMiddleware.d__4.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束---    在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)    在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)    在Microsoft.AspNet.Diagnostics.Entity.MigrationsEndPointMiddleware.d__5.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束---    在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)    在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)    在Microsoft.AspNet.Diagnostics.Entity.DatabaseErrorPageMiddleware.d__6.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束---    在Microsoft.AspNet.Diagnostics.Entity.DatabaseErrorPageMiddleware.d__6.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束---    在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)    在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)    在Microsoft.AspNet.Diagnostics.DeveloperExceptionPageMiddleware.d__7.MoveNext()

1 个答案:

答案 0 :(得分:0)

我认为您在测试查询中忘记了.Include(x => x.File)