【问题标题】:Unable to cast the type 'System.String' to type 'System.Collections.Generic.IEnumerable无法将类型“System.String”转换为类型“System.Collections.Generic.IEnumerable”
【发布时间】:2014-09-14 17:04:32
【问题描述】:

当只有类别要返回时,我的以下查询工作正常,但只要有多个类别,我就会收到 Sequence contains more than one element 错误消息。我想返回所有相关类别。因此,我将 DTO 中的 PostCategory 从字符串更改为列表,这就是我收到转换错误的时候。我还尝试将其更改为IList(of String)IList(of be_Category),并将ToList 添加到ca.CategoryName。那没有用。

我的连接查询:

Public Function SelectByID(id As Integer) As PostDTO Implements IPostRepository.SelectByID
    Dim post As New PostDTO
    Using db As Ctx = New Ctx

        post = From ca In db.be_Categories 
               Join c In db.be_PostCategory On ca.CategoryID Equals (c.CategoryID)
               Join p In db.be_Posts On c.PostID Equals (p.PostID)
               Where p.PostRowID = id
               Select New PostDTO With {
                  .PostCategory = ca.CategoryName, 
                  .PostDateCreated = p.DateCreated, 
                  .PostGuid = p.PostID, 
                  .PostId = p.PostRowID, 
                  .PostText = p.PostContent,
                  .PostTitle = p.Title}).Single
    End Using
    Return post
End Function

那么是否可以将类别名称序列投影到新的 DTO 或其他东西中,或者是否有其他方法可以返回所有类别?我猜由于 CategoryName 是一个字符串,L2E 无法将字符串投影到列表中。我需要GroupBy 将类别字符串投影到新表单中吗?我也试过AsEnumerableString.Join - 都没有成功。

DTO 在下方 - 如果 PostCategory 是一个字符串,那么我可以将单个类别返回到视图中。我希望我已经解释清楚了。

 Public Class PostDTO
    Public PostId As Integer
    Public PostGuid As Guid
    Public PostTitle As String
    Public PostSummary As String
    Public PostText As String
    Public PostDateCreated As DateTime
    Public PostIsPublished As Boolean
    Public PostCategory As IList(Of be_PostCategory)
End Class

编辑: 更新 SelectById:

Public Function SelectByID(id As Integer) As IEnumerable(Of PostDTO) Implements IPostRepository.SelectByID

 Dim post As IEnumerable(Of PostDTO)
 Using db As Ctx = New Ctx
 post = From ca In db.be_Categories 
               Join c In db.be_PostCategory On ca.CategoryID Equals (c.CategoryID)
               Join p In db.be_Posts On c.PostID Equals (p.PostID)
               Where p.PostRowID = id
               Select New PostDTO With {
                  .PostCategory = ca.CategoryName, 
                  .PostDateCreated = p.DateCreated, 
                  .PostGuid = p.PostID, 
                  .PostId = p.PostRowID, 
                  .PostText = p.PostContent,
                  .PostTitle = p.Title}).ToList
    End Using
    End Function

【问题讨论】:

    标签: vb.net join asp.net-mvc-5 entity-framework-6.1


    【解决方案1】:

    当查询返回的元素数量不完全是 1 时,Single 方法会引发异常。尝试从查询末尾删除 .Single()

    此外,我们看不到它被分配给了哪个变量。匿名类型在这里效果很好,但如果你不使用它,请确保它是正确的,即

    Dim result As IEnumerable(Of PostDTO) = From ca In db.be_Categories ...
    

    编辑#1

    我应该添加一些说明。运行LINQ 查询时,期望查询返回任意数量的结果,就像您期望SQL 或类似的那样。但是,如果您只期望一个结果(即Select Top 1 ...),那么您可以使用.Single()。回到您的案例,您的查询针对的是我只能想象的实体框架数据源(Ctx 是这样,对吗?)。如the MSDN documentation 所示,您将返回DbQuery(Of PostDTO),这是LINQ to Entities 针对DbContext 查询返回的数据类型。这种类型,取决于你想用它做什么,可以转换成几个接口。查看它的定义

    Public Class DbQuery(Of TResult) _
        Implements IOrderedQueryable(Of TResult), IQueryable(Of TResult),  _
        IEnumerable(Of TResult), IOrderedQueryable, IQueryable, IEnumerable,  _
        IListSource, IDbAsyncEnumerable(Of TResult), IDbAsyncEnumerable
    

    IEnumberable(Of TResult),在您的情况下 TResult 是 PostDTO,您可以将其转换为,以便您可以枚举结果,providing a lot of functionality 像进一步的查询、排序、获取平均值、最大值、最小值等。希望这个清除它。

    编辑#2

    终于找到了问题的根源。第一部分为您提供一个帖子,但 PostCategory 中没有任何内容。第二部分将类别列表放入单个帖子中。

    post = From ca In db.be_Categories 
           Join c In db.be_PostCategory On ca.CategoryID Equals (c.CategoryID)
           Join p In db.be_Posts On c.PostID Equals (p.PostID)
           Where p.PostRowID = id
           Select New PostDTO With {
              .PostCategory = Nothing, 
              .PostDateCreated = p.DateCreated, 
              .PostGuid = p.PostID, 
              .PostId = p.PostRowID, 
              .PostText = p.PostContent,
              .PostTitle = p.Title}).FirstOrDefault()
    
    post.PostCategory = (From ca In db.be_Categories
                         Join c In db.be_PostCategory On ca.CategoryID Equals (c.CategoryID)
                         Where p.PostRowID = id
                         Select ca.CategoryName).ToList()
    

    【讨论】:

    • 我尝试删除 Single 并抛出 Unable to cast object of type 'System.Data.Entity.Infrastructure.DbQuery`1 to Type PostDTO
    • 再次,您在查询中返回了多个元素。 Dim post As New PostDTO 应该是 Dim post As IEnumerable(Of PostDTO)
    • 我把它切换到IEnumerable(Of PostDTO)。视图仍然抛出Sequence contains more than one element。查看有@ModelType IEnumerable(Of PostDTO)。 Everyting 在只有 1 个类别的页面上很好。但是任何超过 1 个类别的页面都会引发序列错误。
    • 尝试从查询末尾删除.Single()
    • 我删除了 Single,它仍然抛出 Sequence contains more than 1 element。使用 IEnumerable 函数更新原始帖子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-07
    • 2014-03-14
    • 2017-11-24
    • 1970-01-01
    • 2019-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多