当只有一个类别要返回时,我下面的查询工作正常,但一旦有多个类别,我就会收到
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
将类别字符串投影到新表单中?我也尝试过 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 时,Single 方法会引发异常。尝试从查询末尾删除
.Single()
。
此外,我们看不到它被分配给哪个变量。匿名类型在这里效果很好,但如果您不使用匿名类型,请确保它是正确的,即
Dim result As IEnumerable(Of PostDTO) = From ca In db.be_Categories ...
编辑#1
我应该补充一些说明。运行
LINQ
查询时,期望查询返回任意数量的结果,就像您期望 SQL
或类似的操作一样。然而,如果您只期望一个结果(即 Select Top 1 ...
),那么您可以使用 .Single()
。回到您的案例,您的查询是针对实体框架数据源的,我只能想象(Ctx
是这样,对吗?)。如 MSDN 文档 所示,您将返回 DbQuery(Of PostDTO)
,这是针对 DbContext
的 LINQ to Entities 查询返回的数据类型。这种类型可以转换为多个接口,具体取决于您想用它做什么。查看它的定义
Public Class DbQuery(Of TResult) _
Implements IOrderedQueryable(Of TResult), IQueryable(Of TResult), _
IEnumerable(Of TResult), IOrderedQueryable, IQueryable, IEnumerable, _
IListSource, IDbAsyncEnumerable(Of TResult), IDbAsyncEnumerable
IEnumerable(Of TResult)
(在您的情况下TResult
是PostDTO)是您可以强制转换的内容,以便您可以枚举结果,提供很多功能,例如进一步查询、排序、获取平均值、最大值、最小值、等等。希望这能解决问题。
编辑#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()