【问题标题】:How to solve issue "Could not translate expression ...into SQL and could not treat it as a local expression." [duplicate]如何解决“无法将表达式...转换为 SQL 并且无法将其视为本地表达式”的问题。 [复制]
【发布时间】:2014-02-05 22:44:55
【问题描述】:

我的代码如下:

void Main()
{
    var q = from a in Applicants
             where(a.Claims.Any())
             select a.Claims.Sum(c => c.TotalClaimAmount());


    q.Dump();
}

public static class MyExt
{
    public static decimal TotalClaimAmount(this Claim c)
    {
        var t = c.Accommodations.Sum(a => a.AmountClaimed) +
                c.MealAllowances.Sum(ma => ma.AmountClaimed) +
                c.Meals.Sum(m => m.AmountClaimed) +
                c.Mileages.Sum(mi => mi.AmountClaimed) +
                c.Others.Sum(o => o.AmountClaimed) +
                c.ParkingTransits.Sum(pt => pt.AmountClaimed) +
                c.Travels.Sum(tr => tr.AmountClaimed);

        return (decimal)t;
    }
}

当我在 LinqPad 中运行它时,会出现以下问题:

InvalidOperationException:无法将表达式 'a.Claims.Sum(c => c.TotalClaimAmount())' 转换为 SQL 并且无法将其视为本地表达式。

请帮帮我。非常感谢

【问题讨论】:

    标签: c# linq linq-to-sql linq-to-entities linqpad


    【解决方案1】:

    LINQ 无法将 TotalClaimAmount 方法调用转换为 SQL 表达式。

    你可以做的是,从TotalClaimAmount方法中提取表达式,直接在Sum方法调用中使用。

    public static class MyExt {
        public static Func<Claim, decimal> TotalClaimAmountFunc = c =>
            c.Accommodations.Sum(a => a.AmountClaimed) +
            c.MealAllowances.Sum(ma => ma.AmountClaimed) +
            c.Meals.Sum(m => m.AmountClaimed) +
            c.Mileages.Sum(mi => mi.AmountClaimed) +
            c.Others.Sum(o => o.AmountClaimed) +
            c.ParkingTransits.Sum(pt => pt.AmountClaimed) +
            c.Travels.Sum(tr => tr.AmountClaimed);
    
        public static decimal TotalClaimAmount(this Claim c) {
            return TotalClaimAmountFunc(c);
        }
    }
    
    void Main() {
        var q = from a in Applicants
             where(a.Claims.Any())
             select a.Claims.Sum(MyExt.TotalClaimAmountFunc);
    
        q.Dump();
    }
    

    【讨论】:

    • 您好 Lukas,您的代码不工作。它得到了编译错误。 "名称 'TotalClaimAmountFunc' 在当前上下文中不存在"
    • 我忘了MyExt,请查看编辑后的答案。
    • 我怀疑你需要使用 Expression> 而不是 Func
    • 嗨 Lukas,它仍然无法通过编译。错误显示“当前上下文中不存在名称‘TotalClaimAmountExpression’”
    • 嗨乔·阿尔巴哈里。我是你的粉丝。我非常喜欢 Linqpad。希望oracle Intelligent Prompt 能像sql server Intelligent Prompt 一样。那将是非常好的。感谢您将 Linqpad 推向世界。
    【解决方案2】:

    SQL 中没有与您的自定义方法对应的命令。所以编译器无法翻译你的表达式。相反,首先获取您的项目,然后选择您的结果:

     var items = Applicants.Where(a => a.Claims.Any()).ToList();
     var results = items.Select(a => a.Claims.Sum(c => c.TotalClaimAmount());
    

    【讨论】:

    • 当然这会在客户端运行一切,导致 N+1 问题和可怕的性能。
    • 可能。但我没有看到另一种(更好的)方法:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-30
    • 1970-01-01
    • 2020-12-23
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 2016-04-16
    相关资源
    最近更新 更多