【问题标题】:LINQ To Entities doesn't recognize array indexLINQ To Entities 无法识别数组索引
【发布时间】:2012-01-11 08:12:18
【问题描述】:

我的代码中有以下功能

  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;
        }

但是当我尝试这个时,编译器会出现这样的错误。

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;
        }

所以我想知道,为什么?在我的脑海中,我无法为这种行为得到任何答案。谁能解释一下这个悖论?

【问题讨论】:

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


    【解决方案1】:

    这并不神奇:表达式树被转换为关系数据库所理解的 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 查询。

    【讨论】:

    • 谢谢...但是他不能简单地将那个索引的值翻译成 SQL 吗?
    • @mesiesta,不,它不能翻译索引。至于为什么,您将不得不问微软工程师他们为什么不实施它。至于为什么.Contains 有效,嗯,同样的原因:微软工程师实现了它。
    【解决方案2】:

    这个问题是由其他用户提出的,所以它一定是学校作业。

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

    它不能映射到 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;  
    }  
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-09
    • 1970-01-01
    • 2012-04-03
    • 2021-11-06
    • 2012-05-03
    相关资源
    最近更新 更多