63
public List<string> GetpathsById(List<long> id)
{
    long[] aa = id.ToArray();
        long x;
    List<string> paths = new List<string>();
    for (int i = 0; i < id.Count; i++)
    {
        x = id[i];
        Presentation press = context.Presentations.Where(m => m.PresId == aa[i]).FirstOrDefault();
        paths.Add(press.FilePath);
    }
    return paths;
}

This code throws the following exception: The LINQ expression node type 'ArrayIndex' is not supported in LINQ to Entities.

However, if I supply x instead of aa[i] it works.

Why?

David Thompson
  • 2,902
  • 2
  • 18
  • 21
Artur Keyan
  • 7,643
  • 12
  • 52
  • 65

6 Answers6

101

To fix this use a temporary variable:

var tmp = aa[i];
...
m => m.PresId == tmp

In your where clause you have

m => m.PresId == aa[i]

which is a way of expressing a lambda expression. When that is converted to an expression, then converted into a query on your database it finds the aa[i], which is an index into an array. i.e. it doesn't treat it as a constant. Since a translation of an indexer to your database language is impossible it gives the error.

Ashkan Mobayen Khiabani
  • 33,575
  • 33
  • 102
  • 171
George Duckett
  • 31,770
  • 9
  • 95
  • 162
  • It works in linq-to-sql, so why is it impossible in linq-to-entities? – tomsv Mar 18 '13 at 18:36
  • 1
    Basically because "it's not supported in linq to entities". The designers must've decided there wasn't an appropriate translation from an index into an array to the database L2E targets. Possibly they did in L2SQL as it doesn't have to support as much as L2E and so is easier to handle the translation. – George Duckett Mar 18 '13 at 19:35
  • because they screwed up, in other words :) – drogon Jun 11 '13 at 14:57
  • 4
    @drogon: Because it's more complex than it seems is more likely. :) – George Duckett Jun 11 '13 at 14:59
16

Apparently, if you use an array index (aa[i]) inside an expression tree, it tries to convert that into an expression as well.

Just work around it by using a separate variable:

int presId = aa[i];
Presentation press = context.Presentations.Where(m => m.PresId == presId).FirstOrDefault();
Glory Raj
  • 17,397
  • 27
  • 100
  • 203
Trax72
  • 958
  • 5
  • 12
5
 public List<string> GetpathsById(List<long> id)
{
long[] aa = id.ToArray();
    long x;
List<string> paths = new List<string>();
for (int i = 0; i < id.Count; i++)
{
    x = id[i];
    int temp = aa[i];
    Presentation press = context.Presentations.Where(m => m.PresId == temp).FirstOrDefault();
    paths.Add(press.FilePath);
}
return paths;
}

try this

Sender
  • 6,660
  • 12
  • 47
  • 66
2

It cannot be mapped to an SQL type or function.

You are aware you are mixing your list and array with each other. Everything you want doing in this code can be done simply using the list.

The following bit of code will do everything you need it to.

public List<string> GetpathsById(List<long> id) 
{ 
        long x; 
    List<string> paths = new List<string>(); 
    foreach(long aa in id) 
    { 
        Presentation press = context.Presentations.Where(m => m.PresId == aa).FirstOrDefault(); 
        paths.Add(press.FilePath); 
    } 
    return paths; 
} 
Matt Seymour
  • 8,880
  • 7
  • 60
  • 101
1
public List<string> GetpathsById(List<long> id) 
{ 
        long x; 
    List<string> paths = new List<string>(); 
    foreach(long aa in id) 
    { 
        Presentation press = context.Presentations.Where(m => m.PresId == aa).FirstOrDefault(); 
        paths.Add(press.FilePath); 
    } 
    return paths; 
} 

to

public IEnumerable<String> GetpathsById(List<long> id) 
{ 
    foreach(long item in id) 
        yield return = (context.Presentations.Where(m => m.PresId == item).FirstOrDefault()).FilePath
} 

"Short style", but not recomended if you write a lot of other function.

Y K
  • 408
  • 1
  • 5
  • 21
0

Can be simplified to avoid the error:

public List<string> GetpathsById(List<long> id)
{
    return context.Presentations.Where(x => id.Contains(x.PresId)).Select(x => x.FilePath).ToList();
}