[英]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](Func1 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](Func1 operation) at System.Data.Entity.Core.Objects.ObjectQuery
1.GetResults(Nullable1 forMergeOption) at System.Data.Entity.Core.Objects.ObjectQuery
1.<System.Collections.Generic.IEnumerable.GetEnumerator>b__31_0( ) 在 System.Data.Entity.Internal.LazyEnumerator1.MoveNext() at System.Collections.Generic.List
1..ctor(IEnumerable1 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.