所以我试图优化生成网站导航菜单的页面的性能。基本上有一个名为T_product_cat的表,它包含我关心的4个字段:
我需要创建一个顶部导航栏,其中只包含顶级产品类别的名称,然后我需要输出子产品类别及其图像和链接等下拉导航。我有一个基本的ASP:使用嵌套ASP的Repeater控件:Repeater来处理子产品类别
基本上我想开始使用EF开始查询我的数据。最初我做了一个查询,只是拉出顶级项目,然后在转发器的ItemDataBound事件中,我将访问数据并再次查询数据库中的子类别。但这是8x的数据库(因为我有7个顶级类别)。为了加快速度,我一直在尝试初始查询的不同迭代。这是我的最后一个参考:
Using db As New RmpEntities
' query all the items and then all their subitems at the same time so that we don't have to repeatedly hit the database
Dim qry = (
From
productCat In db.T_product_cat
Where
productCat.company_uid = WmsSession.company_uid AndAlso
productCat.enabled = 1 AndAlso
productCat.product_cat_parent_uid = GUIDs.GlobalGuids.RootCategoryUid AndAlso
productCat.product_cat_hide <> 1
Order By
productCat.product_cat_sequence
Select
categoryName = productCat.product_cat_name,
categoryUid = productCat.product_cat_uid,
imagePath = productCat.product_cat_thumbnail_path,
subCategories = (
From
productSubCat In db.T_product_cat
Where
productSubCat.company_uid = WmsSession.company_uid AndAlso
productSubCat.enabled = 1 AndAlso
productSubCat.product_cat_parent_uid = productCat.product_cat_uid AndAlso
productSubCat.product_cat_hide <> 1
Order By
productSubCat.product_cat_sequence
Select
categoryName = productSubCat.product_cat_name,
categoryUid = productSubCat.product_cat_uid,
imagePath = productSubCat.product_cat_thumbnail_path
)
)
rptMainNav.DataSource = qry.ToList()
rptMainNav.DataBind()
End Using
当转发器的ItemDataBound事件触发时,我确实有工作代码来分离结果并将数据绑定到子转发器(此代码有效):
Protected Class CategoryInfo
Public Property categoryName As String
Public Property categoryUid As Guid
Public Property imagePath As String
End Class
Private Sub rptMainNav_ItemDataBound(sender As Object, e As RepeaterItemEventArgs) Handles rptMainNav.ItemDataBound
Dim rItem As RepeaterItem = e.Item
Select Case rItem.ItemType
Case ListItemType.Item, ListItemType.AlternatingItem
Dim dataItem = rItem.DataItem
Dim subRepeater As Repeater = rItem.FindControl("rptSubNav")
Dim parentUid As Guid = dataItem.categoryUid
Dim st = DateTime.Now
Dim x As New List(Of CategoryInfo)
For Each item In dataItem.subCategories
x.Add(New CategoryInfo With {.categoryName = item.categoryName, .categoryUid = item.categoryUid, .imagePath = item.imagePath})
Next
subRepeater.DataSource = x
dTime.Add(New MyTimes With {.g = parentUid, .ts = DateTime.Now - st})
subRepeater.DataBind()
End Select
End Sub
但是如何将通过访问转发器的DataItem返回的Object类型转换为更强类型的对象,以便我可以获得intellisense? 或者有什么方法可以放弃对打字的担忧,只是将查询结果直接用作子转发器的数据源?这是我的第一个目标,但是当我试图采取
时dataItem.subCategories.ToList()
失败了:
Public member 'ToList' on type 'CompensatingCollection(Of VB$AnonymousType_1(Of String,Guid,String))' not found.
当我尝试修改我的CategoryInfo类以使另一个属性保存CategoryInfo类(子类别)列表并让主查询返回结构化数据时(因此我有一个类型要在ItemDataBound中转换)事情失败了更糟。原始查询的.ToList失败,所以我甚至无法进行初始绑定。
处理此问题的正确方法是什么?继续处理表示匿名类型的Object的属性?当然必须有更好的东西。
编辑: 罗伯特 - 谢谢你的建议。事实证明,我没有SubCategories的导航属性。原因是我前面的人设计了数据库,所有顶级类别最终都是人工产品product_cat_parent_uid(只是一些随机的GUID)。它没有指向数据库中的真实产品类别 - 它只是作为占位符。我怀疑为什么他们不只是使用NULL,但改变它为时已晚。无论如何,由于数据库中不存在该项,因此数据库本身没有外键,因为它伪造了链接。数据库不会创建指向不在数据库中的产品类别的产品类别的链接。我确实使用了您的建议来查找有关可以执行的操作的更多信息,并使用本文(Entity Framework - Add Navigation Property Manually)添加了我需要的链接。
问题仍然存在 - 我可以在ItemDataBind事件中获得强类型吗?