Linq Left Join VB.NET To Anonymous Typed List

366 views Asked by At

I am trying to use Linq to accomplish a LEFT OUTER JOIN on list of Anonymous Typed objects where data is Microsoft.SharePoint.Client.ListItem I would like to display all apps. Any apps that have a support record associated with them, I will display those properties. Any apps that do not have an associated support record, I will display those fields empty.

Update - The code below works for the first app returned, which has associated support, but throws the error on the next app in the list which does not have the associated support. I am stumped as to why I am encountering the null reference error during the .MoveNext() on the enumeration. Any help would be much appreciated.

LINQ + DataBinding

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()

Display

<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>

Error

Object reference not set to an instance of an object. Select New With {

Stack Trace

  • 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)
1

There are 1 answers

0
Eric On BEST ANSWER
            Dim AppsList =
            From a In applications.AsEnumerable()
            Group Join s In support.AsEnumerable()
            On Integer.Parse(a("ID")) Equals CType(s("Product"), FieldLookupValue).LookupId Into Group
            From appSupport In Group.DefaultIfEmpty()
            Order By a("Title") Ascending
            Select New With {
                .AppID = a("ID"),
                .AppViewUrl = AppSettings("ViewURL") & "&ListId={" & AppSettings("AppListGuid") & "}&ID=" & a("ID"),
                .AppName = a("Title"),
                .AppContact = ParseMultivaluedUser(a("App_x0020_Contact"), "No Contacts Listed"),
                .SupportEnd = If(appSupport IsNot Nothing AndAlso Date.TryParse(appSupport.Item("End"), New Date), Date.Parse(appSupport.Item("End")).ToShortDateString, Nothing),
                .Licenses = If(appSupport Is Nothing, Nothing, appSupport.Item("Quantity")),
                .StatusIcon = If(appSupport IsNot Nothing, GetStatusIcon(appSupport.Item("End")), "<span class=""StatusIco Tip NoSupport"" title=""No Support Record""> </span>"),
                .SupportTitle = If(appSupport Is Nothing, Nothing, appSupport("Title")),
                .AkaNames = a("AKA_x0020_Names"),
                .AkaOmit = a("AKA_x0020_Omit"),
                .Installs = GetInstalls(a("ID"), a("AKA_x0020_Names"), a("AKA_x0020_Omit"))
            }