繁体   English   中英

EntityFramework 6.4.4 - 如何将集合投影到自定义 object 实现 IEnumerable<t> ?</t>

[英]EntityFramework 6.4.4 - How to project collection to a custom object implementing IEnumerable<T>?

不能将 map 转换为实现 IEnumerable 的自定义 object 吗?

public class BranchCollection : IEnumerable<int>
{
      public IEnumerable<int> BranchIds { get; set; } = new List<int>();
      public BranchPermission() { }
      
      //Custom Code here
}
public class UserDto {
      public BranchCollection Collection { get; set; }
}

尝试使用以下代码投影到 UserDto

dbContext.Users.Select(
  x => new UserDto {
    Collection = new BranchCollection { BranchIds = x.Branches.Select(y => y.BranchId) }
  }
  .ToList();

例外

无法在 LINQ 到 Entities 查询中初始化实现 IEnumerable 'BranchCollection' 的类型。

堆栈跟踪

在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.CheckInitializerType(类型类型) 在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MemberInitTranslator.TypedTranslate(ExpressionConverter parent,MemberInitExpression linq) 在 System.Data。 Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(表达式 linq)在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MemberInitTranslator.TypedTranslate(ExpressionConverter parent,MemberInitExpression linq)在 System.Data.Entity.Core.Objects .ELinq.ExpressionConverter.TranslateExpression(表达式 linq)在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda,DbExpression 输入)在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator。 OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, DbExpression& source, DbExpressionBinding& sourceBinding, DbExpression& lambda) 在 System.Data.Entity.Core.Obj ects.ELinq.ExpressionConverter.MethodCallTranslator.SelectTranslator.Translate(ExpressionConverter 父级,MethodCallExpression 调用)在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter 父级,MethodCallExpression linq)在 System.Data.Entity。 Core.Objects.ELinq.ExpressionConverter.TranslateExpression(表达式 linq)在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.Convert() 在 System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(可空1 forMergeOption) at System.Data.Entity.Core.Objects.ObjectQuery 1.<>c__DisplayClass41_0.b__1() 在 System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func 1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) at System.Data.Entity.Core.Objects.ObjectQuery 1.<>c__DisplayClass41_0.b__0() 在 System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func 1 operation) at System.Data.Entity.Core.Objects.ObjectQuery 1.GetResults(Nullable 1 forMergeOption) at System.Data.Entity.Core.Objects.ObjectQuery 1.<System.Collections.Generic.IEnumerable.GetEnumerator>b__31_0( ) 在 System.Data.Entity.Internal.LazyEnumerator 1.MoveNext() at System.Collections.Generic.List 1..ctor(IEnumerable 1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable 1 来源)

EF 无法理解/启动 class。它旨在适应简单类和 collections 的投影。如果你觉得你必须做类似的事情,那么双重投影:

var userDetails dbContext.Users.Select(x => new 
{
    BranchIds = x.Branches.Select(b => b.BranchId).ToList()
}).ToList()  // This executes the query getting our branch IDs (and include anything from the User we need as well.
.Select(x => new UserDto
{
    Collection = new BranchCollection { BranchIds = x.BranchIds }
}.ToList(); // Project to your custom type from memory.

对于像 class 这样您想包装IEnumerable的地方,我建议将源集合传递到构造函数中以初始化一个私有成员并使其不可变,公开您的枚举器等。如果可以添加/删除项目,则使用您的方法进行调整class 而不是暴露一个包含的集合,以后任何人都可以写

userDto.Collection = new BranchCollection();

... 并且可能把事情弄得一团糟。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM