Bob
Bob

Reputation: 81

lambda expressions in VB.NET... what am I doing wrong?

when I run this C# code, no problems... but when I translate it into VB.NET it compiles but blows due to 'CompareString' member not being allowed in the expression... I feel like I'm missing something key here...

private void PrintButton_Click(object sender, EventArgs e)
{
if (ListsListBox.SelectedIndex > -1)
{
    //Context
    using (ClientOM.ClientContext ctx =
        new ClientOM.ClientContext(UrlTextBox.Text))
    {
        //Get selected list
        string listTitle = ListsListBox.SelectedItem.ToString();
        ClientOM.Web site = ctx.Web;
        ctx.Load(site,
            s => s.Lists.Where(l => l.Title == listTitle));
        ctx.ExecuteQuery();

        ClientOM.List list = site.Lists[0];

        //Get fields for this list
        ctx.Load(list,
            l => l.Fields.Where(f => f.Hidden == false 
      && (f.CanBeDeleted == true || f.InternalName == "Title")));
        ctx.ExecuteQuery();

        //Get items for the list
     ClientOM.ListItemCollection listItems = list.GetItems(
      ClientOM.CamlQuery.CreateAllItemsQuery());
        ctx.Load(listItems);
        ctx.ExecuteQuery();

        // DOCUMENT CREATION CODE GOES HERE

    }

    MessageBox.Show("Document Created!");
}

}

but in VB.NET code this errors due to not being allowed 'CompareString' members in the ctx.Load() methods...

Private Sub PrintButton_Click(sender As Object, e As EventArgs)
    If ListsListBox.SelectedIndex > -1 Then
        'Context
        Using ctx As New ClientOM.ClientContext(UrlTextBox.Text)
            'Get selected list
            Dim listTitle As String = ListsListBox.SelectedItem.ToString()
            Dim site As ClientOM.Web = ctx.Web
            ctx.Load(site, Function(s) s.Lists.Where(Function(l) l.Title = listTitle))
            ctx.ExecuteQuery()

            Dim list As ClientOM.List = site.Lists(0)

            'Get fields for this list
            ctx.Load(list, Function(l) l.Fields.Where(Function(f) f.Hidden = False AndAlso (f.CanBeDeleted = True OrElse f.InternalName = "Title")))
            ctx.ExecuteQuery()

            'Get items for the list
            Dim listItems As ClientOM.ListItemCollection = list.GetItems(ClientOM.CamlQuery.CreateAllItemsQuery())
            ctx.Load(listItems)

            ' DOCUMENT CREATION CODE GOES HERE

            ctx.ExecuteQuery()
        End Using

        MessageBox.Show("Document Created!")
    End If
End Sub

Upvotes: 3

Views: 1789

Answers (2)

Vadim Gremyachev
Vadim Gremyachev

Reputation: 59338

The error

Unhandled Exception: Microsoft.SharePoint.Client.ClientRequestException: The 'CompareString' member cannot be used in the expression.

occurs when using LINQ VB.NET code that queries for SharePoint lists using a comparison operation.

According to KB 2883454:

The cause for this issue is that in VB.NET, the expression:

s = "abc"

is converted to an expression:

0 == Microsoft.VisualBasic.CompilerServices.Operators.CompareString(s, "abc", true)

which is not supported by SharePoint code.

There is no fix for this currently, but a workaround would be to compile the above logic in a C#.NET module and use it in your VB.NET code.

Upvotes: 1

Guffa
Guffa

Reputation: 700362

That is probably because VB is using it's own implementation of the comparison operator, not the implementation in the string class, so the expression can't be used by the Load method.

Try using the Equals method:

ctx.Load(site, Function(s) s.Lists.Where(Function(l) l.Title.Equals(listTitle)))

If that doesn't work, there is an eq operator in LINQ that works in expressions, but I would have to look up the VB syntax for that.

Upvotes: 2

Related Questions