丑陋的LINQ语句,更好的方法吗?

发布于 2024-12-27 18:19:50 字数 926 浏览 3 评论 0原文

我有一个 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() ,但目前由于除了最后两列之外的混乱,我已将其删除。

非常感谢建议!

I have a LINQ statement which is adding up the values of multiple columns, each beginning with 'HH' although there are other columns available:

//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();

Is there any way to tidy this up? I have to do lots of variations of this (in different methods) so it would clear out a lot of 'fluff' if it could be.

Also I'd like to call .GetValueOrDefault() on each column, but currently I've taken this out due to the mess except for the last two columns.

Suggestions much appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

允世 2025-01-03 18:19:50

我想你可以为此使用反射:

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

然后像这样使用它:

return (from e in Data
        where e.SD == date
        select e).ToList().Select(x => GetHHSum(x)).FirstOrDefault();

代码未经过测试

I guess you can use Reflections for this:

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

And then use it like this:

return (from e in Data
        where e.SD == date
        select e).ToList().Select(x => GetHHSum(x)).FirstOrDefault();

Code is not tested

你没皮卡萌 2025-01-03 18:19:50

我可能是错的,因为我不知道你的数据,但在我看来,它们没有完全规范化(重复属性)。
您可能会考虑采用第 3 种正常形式 - 因此创建一个/一些单独的表,该表将按行包含一个值 - 然后在 linq 查询中连接 2 个表。

链接查询看起来会好得多,并且稍后您将能够更改 HH 字段而不更改查询。

I might be wrong because I don't know your data, but it seems to me that they are not fully normalized (repetitive attributes).
You might consider going to the 3rd form normal - thus create a/some separate table that will contain one value by row - and then to join your 2 tables in your linq query.

The link query will look much much better, and you will later be able to change your HH fields without changing your queries.

疑心病 2025-01-03 18:19:50

一个建议是重构上述代码以使用 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() 吗?例如,

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() 。如果将其放入辅助方法中,即使它很冗长,至少也只写一次。

此致,

One suggestion is to refactor the above code to use LINQ method chains and lambdas (personal preference), then extract the select lambda into a separate method. For instance:

// 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()
}

In addition if you wanted to call GetValueOrDefault() on each HHxx property you could wrap this in a further helper function. this really boils down to code preference. Which do you prefer? Seeing .GetValueOrDefault() on the end of each property access or a function around it? e.g.

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

becomes

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

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

Personally I would just go with ordering my HHxx + HHyy code in columns and calling .GetValueOrDefault() on each one. If it's put in a helper method at least its only written once, even if it is verbose.

Best regards,

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文