2

This is my code:

    private void loadList(IQueryable<customer> customers)
    {
        ListView.Items.Clear();
        foreach (var customer in customers)
        {
            ListViewItem item = new ListViewItem(customer.customerNumber.ToString());
            item.SubItems.Add(customer.customerName);
            item.SubItems.Add(customer.contactFirstName);
            item.SubItems.Add(customer.contactLastName);
            item.SubItems.Add(customer.phone);
            item.SubItems.Add(customer.addressLine1);
            item.SubItems.Add(customer.addressLine2);
            item.SubItems.Add(customer.city);
            item.SubItems.Add(customer.state);
            item.SubItems.Add(customer.postalCode);
            item.SubItems.Add(customer.country);
            item.SubItems.Add(customer.salesRepEmployeeNumber.ToString());
            item.SubItems.Add(customer.creditLimit.ToString());

            ListView.Items.AddRange(new ListViewItem[] { item });
        }
    }

    private static readonly Func<customer, string>[] _searches;

    static Main()
    {
        _searches = new Func<customer, string>[]
        {
            (c) => c.customerNumber.ToString(),
            (c) => c.customerName,
            (c) => c.contactFirstName,
            (c) => c.contactLastName,
            (c) => c.phone,
            (c) => c.addressLine1,
            (c) => c.addressLine2,
            (c) => c.city,
            (c) => c.state,
            (c) => c.postalCode,
            (c) => c.country,
            (c) => c.salesRepEmployeeNumber.ToString(),
            (c) => c.creditLimit.ToString(),
        };
    }

    protected virtual void SearchBox_TextChanged(object sender, EventArgs e)
    {

        var search = _searches[SearchItem.SelectedIndex];

        CustomerContext context = new CustomerContext();

        IQueryable<customer> customers = from x in context.customers
                                         where search(x).Contains(SearchBox.Text)
                                         select x;

        loadList(customers);

    }

I am getting this error in the loadList method at the start of the foreach:

'The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.'

How do I solve this? I am fairly new to all this and I've tried a couple things but none of them worked.

halfer
  • 19,824
  • 17
  • 99
  • 186
Luuk Wuijster
  • 6,678
  • 8
  • 30
  • 58
  • Change `_searches = new Func[]` to `_searches = new Expression>[]` then use LinqKit: https://stackoverflow.com/questions/36736203/combining-expression-trees – haim770 Jun 25 '17 at 15:07
  • Okay but in the question Linq is used in a chain (or whatever you call it). How can I do that by using Linq like I do? – Luuk Wuijster Jun 25 '17 at 15:19

1 Answers1

3

The answer was given in a comment by haim770, but it seems you have some troubles with it still, so I'll expand a bit. First install LinqKit nuget package. Then change your search list to contain expressions instead of delegates:

private static readonly Expression<Func<customer, string>>[] _searches;

Then change your search method as follows (add using LinqKit):

IQueryable<customer> customers = from x in context.customers.AsExpandable()
                                 where search.Invoke(x).Contains(SearchBox.Text)
                                 select x;
haim770
  • 48,394
  • 7
  • 105
  • 133
Evk
  • 98,527
  • 8
  • 141
  • 191
  • Okay, thanks for your answer. I did that but I now get the following error: `System.NotSupportedException: 'LINQ to Entities does not recognize the method 'System.String Invoke[customer,String](System.Linq.Expressions.Expression`1[System.Func`2[Linq.customer,System.String]], Linq.customer)' method, and this method cannot be translated into a store expression.'` Any idea how to solve that? I have Linqkit installed and I have added `using LinqKit` – Luuk Wuijster Jun 25 '17 at 16:53
  • 1
    Didn't forget to add `AsExpandable()`? – Evk Jun 25 '17 at 17:08