【问题标题】:Linq : Load parent and child entitiesLinq:加载父子实体
【发布时间】:2013-09-02 15:27:11
【问题描述】:

我正在尝试将数据从我的 SQL Server 2008 数据库加载到服务器端 DTO 以传输到客户端,并且想知道如何加载父实体和子实体的集合。

您可以从模型中看到我正在尝试加载所有用户以及关联到 tblUsermmRole 表中的相关 UserRoles。

当我运行 Linq 查询加载子实体时崩溃,因为查询无法将单个实例加载到集合中。

我可以在单个查询中加载这些实体,还是应该将用户加载到集合中然后迭代地构建子 AccessRoles?

型号

数据传输对象

Public Class User

    Public Property ID As Int32
    Public Property Username As String
    Public Property Password As String
    Public Property AccessRoles As IList(Of UserRoles)

End Class

Public Class UserRoles
    Public Property Role As ApplicationRole
End Class

Public Class ApplicationRole

    Public Property ID As Int32
    Public Property Description As String

End Class

数据加载

Dim var = (From usr In ctx.tblUsers.OrderBy(Function(w) w.username)
              Join useraccess In ctx.tblUsermmRoles On usr.idUser Equals useraccess.idUser
              Join role In ctx.tblUserRoles On role.idRole Equals useraccess.idRole
                Select New User With {.ID = usr.idUser,
                                      .Username = usr.username,
                                      .Password = usr.pwd,
                                      .AccessRoles = New ApplicationRole With {.ID = role.idRole,
                                                                               .Description = role.description}}).ToList

异常消息

{"Unable to cast the type 'Epms.Ui.Models.ApplicationRole' to type 'System.Collections.Generic.IList`1'. LINQ to Entities only supports casting EDM primitive or enumeration types."}

堆栈跟踪

   at System.Data.Objects.ELinq.ExpressionConverter.ValidateAndAdjustCastTypes(TypeUsage toType, TypeUsage fromType, Type toClrType, Type fromClrType)
   at System.Data.Objects.ELinq.ExpressionConverter.GetCastTargetType(TypeUsage fromType, Type toClrType, Type fromClrType, Boolean preserveCastForDateTime)
   at System.Data.Objects.ELinq.ExpressionConverter.CreateCastExpression(DbExpression source, Type toClrType, Type fromClrType)
   at System.Data.Objects.ELinq.ExpressionConverter.ConvertTranslator.TranslateUnary(ExpressionConverter parent, UnaryExpression unary, DbExpression operand)
   at System.Data.Objects.ELinq.ExpressionConverter.UnaryTranslator.TypedTranslate(ExpressionConverter parent, UnaryExpression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.MemberInitTranslator.TypedTranslate(ExpressionConverter parent, MemberInitExpression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.JoinTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
   at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod)
   at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
   at System.Data.Objects.ELinq.ExpressionConverter.Convert()
   at System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
   at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
   at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
   at System.Data.Entity.Internal.Linq.InternalQuery`1.GetEnumerator()
   at System.Data.Entity.Infrastructure.DbQuery`1.System.Collections.Generic.IEnumerable<TResult>.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Epms.Ui.DataProvider.DataAccess.EntityProvider.GetUsers() in C:\Users\phil.murray\Desktop\Data Provider\Epms.Ui.DataProvider\DataAccess\EntityProvider.vb:line 24
   at Epms.Ui.DataProvider.DataProvider.VB$StateMachine_0_GetUsers.MoveNext() in C:\Users\phil.murray\Desktop\Data Provider\Epms.Ui.DataProvider\DataProvider.vb:line 27

【问题讨论】:

  • 我的 VB 不是很好,所以这可能是完全错误的语法,但是像 .AccessRoles = New List(Of ApplicationRole) From { New ApplicationRole With {.ID = role.idRole, .Description = role.description}} 这样的东西怎么样?
  • 这给了我另一个例外——无法转换类型“System.Collections.Generic.List1' to type 'System.Collections.Generic.IList1”。 LINQ to Entities 仅支持转换 EDM 基元或枚举类型。

标签: .net vb.net linq entity-framework .net-4.5


【解决方案1】:

最后我改为 UserRoles 类来保存 ID int 值

Public Class UserRoles
    Public Property Role As int32
End Class

然后通过下面的 Linq 查询加载数据。

Return (From usr In ctx.tblUsers.Include("tblUsermmRoles")
          Select New User With {.ID = usr.idUser,
                                .Username = usr.username,
                                .Password = usr.pwd,
                                .AccessRoles = usr.tblUsermmRoles.Select(Function(r) r.idRole)}).ToList

【讨论】:

  • 您最初的方法是不必要的内在(并且无法解释“IList 现实”)。很高兴您发布了一个非常合适的代码。无论如何,这并不完全代表您原始问题的实际解决方案(为什么我会收到此错误?)。仍然不确定为什么我写的解决方案(确实回答了您的原始问题)在您的计算机上不起作用;但是好吧...重要的是,最后,事情做得很好。
猜你喜欢
  • 1970-01-01
  • 2020-11-04
  • 2021-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-11
相关资源
最近更新 更多