This is a migrated thread and some comments may be shown as answers.
Issue with LINQ contains
3 Answers 49 Views
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Art Kedzierski
Top achievements
Rank 2
Art Kedzierski asked on 29 Jan 2013, 06:43 PM
I'm having issues filtering an OpenAccess model with LINQ. Here's the scenario: I'm generating an array of IDs from the selected items of a RadGrid that I want to use to filter the EntitiesModel:

public ArrayList GetTelerikGridSelections(Telerik.Web.UI.RadGrid grid)
{
    ArrayList selectedItems = new ArrayList();
    if (grid.MasterTableView.DataKeyNames.Length > 0)
    {
        string key = grid.MasterTableView.DataKeyNames[0];
        for (int i = 0; i < grid.SelectedItems.Count; i++)
        {
            selectedItems.Add((int)grid.MasterTableView.DataKeyValues[grid.SelectedItems[i].ItemIndex][key]);
        }
    }
 
 
    using (GlobalLabManager.GLMEntitiesModel ctx = new GlobalLabManager.GLMEntitiesModel())
    {
        var q = from i in ctx.Reservations
                where selectedItems.Contains(i.ResourceFK)
                select i;
        schd_Resources.DataSource = q;
        schd_Resources.Rebind();
    }
}

However, I get the following error when I run the code. No mention of it in any of my searches.

An exception occured during the execution of 'Extent<GlobalLabManager.Reservation>().Where(r => value(Schedule+<>c__DisplayClass0).selectedItems.Contains(Convert(r.ResourceFK)))'. Failure: Execution of 'System.Collections.ArrayList:Contains(Object)' on the database server side currently not implemented.
See InnerException for more details.
Complete Expression:
.Call System.Linq.Queryable.Where(
    .Constant<Telerik.OpenAccess.Query.ExtentQueryImpl`1[GlobalLabManager.Reservation]>(Extent<GlobalLabManager.Reservation>()),
    '(.Lambda #Lambda1<System.Func`2[GlobalLabManager.Reservation,System.Boolean]>))
 
.Lambda #Lambda1<System.Func`2[GlobalLabManager.Reservation,System.Boolean]>(GlobalLabManager.Reservation $r) {
    .Call (.Constant<Schedule+<>c__DisplayClass0>(Schedule+<>c__DisplayClass0).selectedItems).Contains((System.Object)$r.ResourceFK)

Anyone else seen this error before? Or have a better idea how to accomplish what I'm looking for?

3 Answers, 1 is accepted

Sort by
0
Accepted
Viktor Zhivkov
Telerik team
answered on 30 Jan 2013, 10:32 AM
Hello Art,

The exceptions is caused by the fact that you have used weakly typed ArrayList in the LINQ query instead of a more strongly typed generic collection.
If you know the type of the item keys you should use the proper generic type - for example:
1.List<int> selectedITems = new List<int>();
2....
3.selectedItems.Add((int)grid.MasterTableView.DataKeyValues[grid.SelectedItems[i].ItemIndex][key]);
4....
5.var q = from i in ctx.Reservations
6.      where selectedItems.Contains(i.ResourceFK)
7.      select i;

That way your LINQ query will work as expected. Please keep in mind that the type of the i.ResourceFK should match the type of the items in the selectedItems collection.
In general the usage of System.ArrayList type is considered bad practice after the introduction of generics and should be avoided.

Greetings,
Viktor Zhivkov
the Telerik team
Q3'12 SP1 of OpenAccess ORM packs Multi-Table Entities mapping support. Check it out.
0
Art Kedzierski
Top achievements
Rank 2
answered on 30 Jan 2013, 03:26 PM
That fixed that issue (thanks!), but I'm still having a hard time figuring out the correct way to filter the OpenAccessLinqDataSource. I see how to set up a filter based on a single parameter (WHERE EQUALS, etc), but I don't see how to do something equivalent to a SQL 'WHERE IN' clause. Now that I have a properly cast List<int> of IDs from a control (in this case a RadGrid) I need to filter the incoming appointments of a RadScheduler, limiting the SELECT results. If I were writing SQL, It would be something like:  

SELECT * FROM [Reservations] WHERE [ResourceFK] IN (<List of selected IDs from RadGrid>)

Is this even possible with an OpenAccessLinqDataSource, or should I be looking at a different data source type?
0
Accepted
Doroteya
Telerik team
answered on 04 Feb 2013, 11:49 AM
Hello Art,

In order to filter the result set in the way you need, I suggest you to use the Selecting event of the OpenAccessLinqDataSource. The following snippet demonstrates the approach:
protected void OpenAccessLinqDataSource2_Selecting(object sender, Telerik.OpenAccess.Web.OpenAccessLinqDataSourceSelectEventArgs e)
{
  //... Assign the value of the selectedItems list here ... 
  using (EntitiesModel ctx = new EntitiesModel())
  {
    e.Result = ctx.Reservations.Where(r => selectedItems.Contains(r.ResourceFK).ToList();
  }
}

The basic idea is that since the Selecting event occurs before the data-retrieval you could attach a custom filtering expression to the result. You can find details about how the solution works in the second part of this documentation article (How to: Change the Filter Expression Runtime).

Note that in real live scenarios we recommend the following ways to manage the OpenAccessContext:
- Using a master page
- Using a custom Http Module
- Using an Http Context

I hope that works for you. If you have any additional questions, do not hesitate to get back to us.

 

Kind regards,
Doroteya
the Telerik team
Q3'12 SP1 of OpenAccess ORM packs Multi-Table Entities mapping support. Check it out.
Tags
LINQ (LINQ specific questions)
Asked by
Art Kedzierski
Top achievements
Rank 2
Answers by
Viktor Zhivkov
Telerik team
Art Kedzierski
Top achievements
Rank 2
Doroteya
Telerik team
Share this question
or