无法将类型'System.String'强制转换为'System.Collections.Generic.IEnumerable'

时间:2014-07-23 13:25:28

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

我的查询在只有要返回的类别时工作正常,但只要有多个我收到Sequence contains more than one element错误消息。我想返回所有相关类别。所以我将DTO中的PostCategory从字符串更改为List,这就是我得到了转换错误。我还尝试将其更改为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将类别字符串投影到新表单中?我也试过了AsEnumerable,我尝试了String.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

1 个答案:

答案 0 :(得分:0)

当查询返回的元素数量不正确时,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

最后了解问题的根源。第一部分为您提供了一个Post,但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()