简体   繁体   English

如何修复此LINQ以便将一对val视为一个独特的值?

[英]How can I fix this LINQ so that it treats a pairs of vals as a distinct value?

The database I'm working with stores a pair of double values in two integer columns. 我正在使用的数据库在两个整数列中存储一对double值。

IOW, Department is a double with values such as 42.12, but is stored in a Dept column (which holds 42 in this case) and a Subdept column (which holds 12 in this case). IOW,Department是一个带有42.12等值的double,但存储在Dept列(在这种情况下保存42)和Subdept列(在这种情况下保存12)。 Don't ask me why (because you'd be disappointed; I can't tell you why, because I don't know). 不要问我为什么(因为你会失望;我不能告诉你为什么,因为我不知道)。

I need to get a subset of data such as "all the department records between 8.79 and 98.87" 我需要获取一些数据,例如“8.79和98.87之间的所有部门记录”

I have this code: 我有这个代码:

public IEnumerable<InventoryItem> GetDepartmentRange(double deptBegin, double deptEnd, string dbContext)
{
    LoadInventoryItems(dbContext);
    // Break the doubles into their component parts:
    var deptStartWhole = (int)Math.Truncate(deptBegin);
    var startFraction = (int)((deptBegin - deptStartWhole) * 100);
    var deptEndWhole = (int)Math.Truncate(deptEnd);
    var endFraction = (int)((deptBegin - deptEndWhole) * 100);

    return inventoryItems
        .Where(d => d.dept >= deptStartWhole)
        .Where(e => e.subdept >= startFraction)
        .Where(f => f.dept <= deptEndWhole)
        .Where(g => g.subdept >= endFraction)
        //.Where(g => g.subdept <= endFraction)
        .OrderBy(o => o.dept)
        .ThenBy(s => s.subdept);
}

...but it doesn't quite work - with the above query (Depts between 8.79 and 98.87) it shows depts that are 98.88, which is one beyond what I want. ...但它不是很有效 - 使用上面的查询(De.79在8.79和98.87之间)它显示的是98.88的depts,这超出了我想要的范围。

I tried the commented-out line, but that made it even worse (nothing returned at all). 我尝试了注释掉的线路,但这使它更糟糕(根本没有返回)。

My intuition tells me I may need a "let" here, but don't know just how to go about it. 我的直觉告诉我,我可能需要一个“让”,但不知道如何去做。

UPDATE UPDATE

在此输入图像描述

Your endFraction calculation is wrong: 你的endFraction计算是错误的:

public IEnumerable<InventoryItem> GetDepartmentRange(double deptBegin, double deptEnd, string dbContext)
{
    LoadInventoryItems(dbContext);
    // Break the doubles into their component parts:
    int deptStartWhole = (int)Math.Truncate(deptBegin);
    int startFraction = (int)((deptBegin - deptStartWhole) * 100);
    int deptEndWhole = (int)Math.Truncate(deptEnd);
    int endFraction = (int)((deptEnd - deptEndWhole) * 100);

    return inventoryItems
        .Where(d => d.dept >= deptStartWhole)
        .Where(e => e.subdept >= startFraction)
        .Where(f => f.dept <= deptEndWhole)
        .Where(g => g.subdept >= endFraction)
        .OrderBy(o => o.dept)
        .ThenBy(s => s.subdept);
}

You are using a wrong variable in your calculation here: 您在计算中使用了错误的变量:

var endFraction = (int)((deptBegin - deptEndWhole) * 100);

Replace deptBegin with deptEnd to fix this. 更换deptBegindeptEnd来解决这个问题。

Making this change appears to produce the desired values when tested with the following code: 使用以下代码进行测试时,进行此更改似乎会产生所需的值:

public void ShowDeptRange(double deptBegin, double deptEnd)
{
    // Break the doubles into their component parts:
    var deptStartW = (int)Math.Truncate(deptBegin);
    var deptStartF = (int)((deptBegin - deptStartW) * 100);
    var deptEndW = (int)Math.Truncate(deptEnd);
    var deptEndF = (int)((deptEnd - deptEndW) * 100);

    Console.WriteLine("{0}.{1}, {2}.{3}",
        deptStartW, deptStartF, deptEndW, deptEndF);
}

void Main()
{
    ShowDeptRange(8.79, 98.87);
}

Also see this answer , which addresses problems with your query's logic. 请参阅此答案该答案解决了查询逻辑的问题。

Your condition is not correct. 你的病情不正确。 Consider following: 考虑以下:

int deptStartWhole = 8;
int startFraction = 79;
int deptEndWhole = 98;
int endFraction = 87;

and your condition is: 你的条件是:

d.dept >= deptStartWhole && d.subdept >= startFraction
&& d.dept <= deptEndWhole && d.subdept <= endFraction

it will not return row with dept = 12 and subdept = 32 , because 32 >= 79 ( d.subdept >= startFraction check) is not true. 它不会返回dept = 12subdept = 32 ,因为32 >= 79d.subdept >= startFraction check)不成立。

I think your condition should be 我认为你的病情应该是

((d.dept == deptStartWhole && d.subdept >= startFraction) || d.dept > deptStartWhole)
&& ((d.dept == deptEndWhole && d.subdept <= endFraction) || d.subdept < deptEndWhole)

It checked subdept only when dept is exactly the same, and otherwise just check dept part, because that's the important one. 它仅在dept完全相同时检查subdept ,否则只检查dept部分,因为那是重要的部分。

return inventoryItems
    .Where(d => ((d.dept == deptStartWhole && d.subdept >= startFraction) || d.dept > deptStartWhole)
                && ((d.dept == deptEndWhole && d.subdept <= endFraction) || d.subdept < deptEndWhole))
    .OrderBy(o => o.dept)
    .ThenBy(s => s.subdept);

Since in you're example you're multiplying the fraction by 100, i'm assuming the subdept value would only have two digits. 因为在你的例子中你将分数乘以100,我假设subdept值只有两位数。 If it's the case, perhaps you could try the following code: 如果是这种情况,也许您可​​以尝试以下代码:

public IEnumerable<InventoryItem> GetDepartmentRange(double deptBegin, double deptEnd, string dbContext)
{           
  LoadInventoryItems(dbContext);

  return inventoryItems
    .Where(d => ((d.dept * 100 + d.subdept) >= deptBegin * 100) &&       
                ((d.dept * 100 + d.subdept) <= deptEnd * 100))
    .OrderBy(o => o.dept)
    .ThenBy(s => s.subdept);
}

A suggestion: create a function that takes in the deptNumber and deptSubNumber , and returns a decimal . 建议:创建一个接受deptNumberdeptSubNumber ,并返回一个decimal Then, use that function in-line in the .Where() statement to process the numbers as a single number, rather than using separate logic (treating dept and sub-dept separately) . 然后,在.Where()语句中使用该函数在线处理数字作为单个数字,而不是使用单独的逻辑(分别处理dept和sub-dept)。

An alternative suggestion: is it possible to create a calculated column on the database that simply combines the two fields together in the database, and returns it as a decimal? 另一种建议:是否可以在数据库上创建一个计算列,它只是将数据库中的两个字段组合在一起,并将其作为小数返回?

Then, use that function in-line in the .Where() statement to process the numbers as a single number, rather than using separate logic (treating dept and sub-dept separately). 然后,在.Where()语句中使用该函数在线处理数字作为单个数字,而不是使用单独的逻辑(分别处理dept和sub-dept)。

Following this, all of the department/sub-department logic in the C# code would be moot. 在此之后,C#代码中的所有部门/子部门逻辑都没有实际意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM