我怎样才能使这个Linq声明更复杂

时间:2013-10-31 15:34:09

标签: linq linq-to-entities

经过数小时的研究后,我仍然无法缩短此查询,但肯定有办法......我当前的查询看起来像是这样

decimal Cost = db.U_MBP
    .Where(w => w.Model == ModelNumber)
    .Select(s => s.Cost ?? 0)
    .FirstOrDefault();
double Margin = db.U_MBP
    .Where(w => w.Model == ModelNumber)
    .Select(s => s.Margin ?? 0)
    .FirstOrDefault();
decimal BasePrice = Cost / (decimal)Margin;

我最初想要完成的是一个1合1的linq语句,类似于

decimal BasePrice = db.U_MBP
    .Where(w => w.Model == ModelNumber)
    .Select(s => s.Cost ?? 0 / (decimal)s.Margin ?? 0)
    .FirstOrDefault();

但我无法克服施法错误。

LINQ to Entities查询不支持强制转换为十进制,因为无法推断出所需的精度和比例信息。

你们有人可以帮忙吗?

回答D的帮助

decimal BasePrice = (decimal)(db.Utilities_ModelsBasePrices
                .Where(w => w.Model == ModelNumber)
                .Select(s => (s.Margin == null || s.Margin == 0) ? (double)0m :
                                    ((double)s.Cost) / (double)s.Margin)
                .FirstOrDefault());

1 个答案:

答案 0 :(得分:4)

问题在于:

.Select(s => s.Cost ?? 0 / (decimal)s.Margin ?? 0)

??运算符的优先级低于/运算符,因此它有效地计算:

.Select(s => s.Cost ?? (0 / (decimal)s.Margin) ?? 0)

转换为

if (s.Cost == null)
   if((0 / (decimal)s.Margin))== null
       return 0;
   else
       return (0 / (decimal)s.Margin);      
else
    return s.Cost;

使用??和其他运算符时,您需要添加parens:

decimal BasePrice = db.U_MBP
    .Where(w => w.Model == ModelNumber)
    .Select(s => (s.Cost ?? 0) / ((decimal)s.Margin ?? 0))
    .FirstOrDefault();

但是,如果s.Margin为null或0,您将获得除零异常。我建议:

decimal BasePrice = (decimal)(db.U_MBP
    .Where(w => w.Model == ModelNumber)
    .Select(s => (s.Margin == null || s.Margin == 0) ? 0.0 :
                      ((double)s.Cost ?? 0) / s.Margin)
    .FirstOrDefault());

Eric Lippert recently posted关于他博客上的空合并优先权。