LINQ To Entities无法识别数组索引

时间:2011-12-02 09:02:58

标签: c# linq asp.net-mvc-3 linq-to-entities

我的代码中有以下功能

  public List<string> GetpathsById(List<long> id)
        {

            List<string> paths = new List<string>();
            for (int i = 0; i < id.Count; i++)
            {

                Presentation press = context.Presentations.Where(m => m.PresId == id[i]).FirstOrDefault();
                paths.Add(press.FilePath);
            }
            return paths;
        }

但是当我尝试这个时,compiller会得到这样的错误。

LINQ to Entities does not recognize the method 'Int64 get_Item(Int32)' method, and this method cannot be translated into a store expression.

然后我尝试做这样的事情,一切正常。

  public List<string> GetpathsById(List<long> id)
        {
             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 == x).FirstOrDefault();
                paths.Add(press.FilePath);
            }
            return paths;
        }

所以我想知道,为什么?在我的脑海里,我无法得到任何答案。任何人都可以解释这个悖论吗?

2 个答案:

答案 0 :(得分:2)

没有魔力:表达式树被翻译成SQL查询,这是关系数据库所理解的。你几乎可以在表达式树中做任何事情。遗憾的是并非所有操作都已实施请考虑以下示例:

Presentation press = context
   .Presentations
   .Where(m => SomeCustomFunctionThatUsesUnmanagedPInvokeCode(m.PresId))
   .FirstOrDefault();

您希望生成的SQL查询是什么?

阵列索引器就是这种情况。它们无法转换为SQL查询。

据说,在您的情况下,以下内容可能会更简单一些:

public List<string> GetpathsById(List<long> id)
{
    return
        (from p in context.Presentations
         where id.Contains(p.PresId)
         select p.FilePath
        ).ToList();
}

.Contains方法将被翻译为SQL IN子句。这样可以避免像在每个迭代中的示例一样向数据库发送多个SQL查询。

答案 1 :(得分:1)

这个问题是由其他用户提出的,因此必须是学校作业。

基本上我给了其他用户同样的答案。

它无法映射到SQL类型或函数。

您可以在此代码中完成所有操作,只需使用列表并以稍微不同的方式迭代它。

以下代码将完成您需要的所有操作。

public List<string> GetpathsById(List<long> id)  
{
    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;  
}