Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 丑陋的LINQ陈述,更好的方式?_C#_.net_Linq_Linq To Entities - Fatal编程技术网

C# 丑陋的LINQ陈述,更好的方式?

C# 丑陋的LINQ陈述,更好的方式?,c#,.net,linq,linq-to-entities,C#,.net,Linq,Linq To Entities,我有一个LINQ语句,它将多个列的值相加,每个列都以“HH”开头,尽管还有其他列可用: //TODO Clean up this mess var query1 = (from e in Data where e.SD == date select e).Select(x => x.HH01 + x.HH16 + x.HH17 + x.HH18 + x.HH19 + x.HH20 + x.HH21 + x.HH22 + x

我有一个LINQ语句,它将多个列的值相加,每个列都以“HH”开头,尽管还有其他列可用:

//TODO Clean up this mess
var query1 = (from e in Data
                where e.SD == date
                select e).Select(x =>   x.HH01 + x.HH16 + x.HH17 + x.HH18 + x.HH19 + x.HH20 + x.HH21 + x.HH22 + x.HH23 +
                                        x.HH24 + x.HH25 + x.HH26 + x.HH27 + x.HH28 + x.HH29 + x.HH30 + x.HH31 + x.HH32 + 
                                        x.HH33 + x.HH34 + x.HH35 + x.HH36 + x.HH37 + x.HH38 + x.HH39 + x.HH40 + x.HH41 +
                                        x.HH42 + x.HH43 + x.HH44 +x.HH45 + x.HH46 + x.HH47 + x.HH48 + x.HH49.GetValueOrDefault()+
                                        x.HH50.GetValueOrDefault());

return query1.FirstOrDefault();
有什么办法可以收拾一下吗?我必须做很多变化(用不同的方法),所以如果可能的话,它会清除很多“绒毛”

此外,我还想对每一列调用
.GetValueOrDefault()
,但由于最后两列之外的混乱,目前我已将其删除


非常感谢您的建议

我想你可以使用反射来实现这一点:

double GetHHSum<T>(T x) where T : class
{
   double result = 0;

   var properties = typeof(T).GetProperties();
   foreach (var property in properties)
   {
       if (property.Name.StartsWith("HH"))
          sum += Convert.ToSingle(property.GetValue(x)).GetValueOrDefault();
   }

   return result;
}

代码未经测试

我可能错了,因为我不知道您的数据,但在我看来,它们没有完全规范化(重复属性)。 您可能会考虑进入第三范式正常-从而创建一个/一些单独的表,将包含一个值逐行-然后加入您的2个表在您的LINQ查询。
链接查询看起来会更好,以后您可以在不更改查询的情况下更改HH字段。

一个建议是重构上述代码,使用LINQ方法链和lambda(个人首选项),然后将select lambda提取到单独的方法中。例如:

// Note select e and .Select(x => x..) is redundant. Only need one
var query1 = Data.Where(e => e.SD == date).Select(SumOfHValues);
return query1.FirstOrDefault();

// Note types are unclear in your question so I've put dummy placeholders
private static QueryResultType SumOfHValues(YourInputClassType x)
{
    // Nothing wrong with this syntactically, it will be faster than a 
    // reflection solution
    // 
    // Algorithmic code tends to have this sort of look & feel. 
    // You could make it more readable
    // by commenting exactly what the summation is doing and 
    // with a mathematical notation or link to documentation / web source
    return x.HH01 + x.HH16 + x.HH17 + x.HH18 + 
           x.HH19 + x.HH20 + x.HH21 + x.HH22 + 
           x.HH23 + x.HH24 + x.HH25 + x.HH26 + 
           x.HH27 + x.HH28 + x.HH29 + x.HH30 + 
           x.HH31 + x.HH32 + x.HH33 + x.HH34 + 
           x.HH35 + x.HH36 + x.HH37 + x.HH38 + 
           x.HH39 + x.HH40 + x.HH41 + x.HH42 + 
           x.HH43 + x.HH44 + x.HH45 + x.HH46 + 
           x.HH47 + x.HH48 + 
           x.HH49.GetValueOrDefault() +
           x.HH50.GetValueOrDefault()
}
此外,如果要对每个HHxx属性调用GetValueOrDefault(),可以将其包装到另一个帮助函数中。这实际上可以归结为代码偏好。你喜欢哪一种?在每个属性访问或其周围的函数的末尾看到.GetValueOrDefault()?e、 g

return x.HH01 + x.HH16 + x.HH17 + x.HH18
变成

return Get(x.HH01) + Get(x.HH16) + Get(x.HH17) + Get(x.HH18) ... 

private static HClassType Get(HClassType input)
{ 
    return input.GetValueOrDefault();
} 
就我个人而言,我只需要在列中对我的HHxx+HHyy代码进行排序,并在每个列上调用.GetValueOrDefault()。如果它被放入一个助手方法中,那么它至少只被写入一次,即使它是冗长的


致以最诚挚的问候,

您必须添加的值是否始终相同?所以总是HH01,HH16,HH17?你用的是哪种LINQ提供者?@WouterdeKort:我猜不是,因为他必须做变异…@FarligOpptreden我的意思是如果它是X=HH01+HH02,Y=HH03+HH01。然后你可以移动X和Y作为eThe的属性,HH等都是不同的列,我必须对它们进行修改(否则它们只是不相关的数字)。我正在使用具有Oracle后端的LINQ to实体。这不起作用,因为提供程序不知道如何将
GetHHSum
转换为SQL。我已编辑了我的答案。不是,它不会尝试将其转换为SQL,只是使用Linq帮助程序扩展来选择正确的内容。哦,是的,对不起。如果有帮助的话,请把答案打上记号。谢谢。我没有问这个问题,我只是在你的回答中指出了问题;-)轻微增强。更改为
typeof(T).GetProperties().Where(p=>p.Name.StartsWith(“HH”))
,然后无需在
for
循环中检查此项。数据与我无关,我只有一个数据库表(我无法以任何方式更改或修改)并且必须提取数据,因为在发布的代码中没有任何东西显示数据不是标准化的Cosmin:事实上,我的答案是基于很多假设的。让我感兴趣的是问题中“列”一词的用法。而且,凭借经验,很容易识别此类问题并从根本上解决它们(数据)
return Get(x.HH01) + Get(x.HH16) + Get(x.HH17) + Get(x.HH18) ... 

private static HClassType Get(HClassType input)
{ 
    return input.GetValueOrDefault();
}