【发布时间】:2015-06-22 13:09:39
【问题描述】:
我正在尝试使用 Linq 在数据为 Microsoft.SharePoint.Client.ListItem 的匿名类型对象列表上完成 LEFT OUTER JOIN 我想显示所有应用程序。任何具有与其关联的支持记录的应用程序,我都会显示这些属性。任何没有相关支持记录的应用,我会将这些字段显示为空。
更新 - 下面的代码适用于返回的第一个应用程序,该应用程序具有关联的支持,但会在列表中的下一个没有关联支持的应用程序上引发错误。我很难理解为什么在枚举的.MoveNext() 期间遇到空引用错误。任何帮助将非常感激。
LINQ + 数据绑定
Dim q =
From a In apps.AsEnumerable()
Group Join s In support.AsEnumerable()
On a("Title").ToString() Equals CType(s("Product"), FieldLookupValue).LookupValue Into Group
From ajs In Group.DefaultIfEmpty()
Select New With {
.Name = a("Title"),
.SupportEnd = IIf(ajs Is Nothing, "Unsupported", ajs("End"))
}
gvApps.DataSource = q.AsQueryable()
gvApps.DataBind()
显示
<asp:GridView ID="gvApps" runat="server" CssClass="GvApps"
AutoGenerateColumns="false" EnableViewState="true"
GridLines="None" CellSpacing="-1">
<Columns>
<asp:TemplateField HeaderText="Application">
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "Name")%>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Support End">
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "SupportEnd")%>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
错误
对象引用未设置为对象的实例。 Select New With {
堆栈跟踪
- SPDataAccess._Lambda$__5(VB$AnonymousType_0`2 $VB$It1, ListItem appWithSupport)
- System.Linq.d__31`3.MoveNext()
- System.Web.UI.WebControls.GridView.CreateChildControls(IEnumerable dataSource, Boolean dataBinding)
【问题讨论】:
-
SharePoint 列表不是表格,不应以这种方式处理。更糟糕的是,
AsEnumerable()调用将 all ListItems 强制加载到内存中,但不是所有数据。例如,Product查找可能未加载。 -
@PanagiotisKanavos 我完全了解您的两点。我无权更改 SharePoint 列表数据的排列或存储方式,但我必须从中获取数据。
-
@PanagiotisKanavos 位于支持列表中的产品查找已与应用程序列表一起加载。我只从我需要的每个 SharePoint 列表中带回了 4 个字段。你可以使用这个库来做到这一点。
-
重点是 - 您不是在两个列表之间进行 JOIN,而是将所有内容加载到内存中,然后尝试对对象进行 LINQ 连接。只是不要致电
AsEnumerable()。最好的选择是尝试编写一个实际执行连接并返回您想要的内容的 CAML 查询。 LINQ to SP 是对 CAML 的抽象。如果你不能这样做,你也不能编写 LINQ 查询。 -
此外,NullReferenceException 应该很容易调试 - 只需附加调试器并查看引发异常的位置。由于您不使用 LINQ to SP,因此您可以创建临时变量,甚至可以在 LINQ 中使用
let语句来存储临时对象以供检查。
标签: vb.net linq linq-to-objects anonymous-types