首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用多个标准在LINQ中进行分组?

如何使用多个标准在LINQ中进行分组?
EN

Stack Overflow用户
提问于 2019-05-07 20:26:28
回答 2查看 133关注 0票数 0

是否有一种方法可以在ObservableCollection中获得所有可能的组合?

我有个这样的模特:

代码语言:javascript
运行
复制
    public string MyProperty { get; set; }
    public string MyProperty2 { get; set; }
    public string MyProperty3 { get; set; }
    public string MyProperty4 { get; set; }
    public string MyProperty5 { get; set; }
    public string MyProperty6 { get; set; }
    public string MyProperty7 { get; set; }
    public string MyProperty8 { get; set; }

我用电子表格中的数据填充这个模型,但是有些值有零值或空值(我需要排除这些值)。是否有一种方法可以得到所有可能具有相同模式的组合?

例如,所有属性中的值与0不同的所有组合,以及只有一个属性和值的所有组合,以及其他属性为零的组合,等等。

到目前为止,我有这样的事情:

代码语言:javascript
运行
复制
var group1 = _sourceStructure.Where(c => c.MyProperty != "0" && c.MyProperty2 != "0" && c.MyProperty3 != "0" && c.MyProperty4 != "0"
        && c.MyProperty5 != "0" && c.MyProperty6 != "0" && c.MyProperty7 != "0" && c.MyProperty8 != "0");

但是,我需要用30多个案例来评估,是否有办法使用LINQ或其他解决方案获得所有可能的组合?

我希望使用集合中的值构建SQL查询,但是如果值为0或为空,则不会将该值添加到查询中。我希望获得具有相同模式的所有组合,以便能够将具有相同模式的所有项放入SQL中的in中。

输出数据如下所示:

代码语言:javascript
运行
复制
string query = @"Select field1, field2, field3, fieldn FROM table WHERE "

query = query + "field1 = " + _sourceStructure.MyProperty1;

query = query + "fieldN =  " + _sourceStructure.MyPropertyN;

基本上,我不在乎价值是多少。我只需要用相同模式的所有可能组合对集合进行分组。

Excel中原始文件中的数据示例:

代码语言:javascript
运行
复制
       MyProperty1 MyPropert2 MyPropertN
Row1      0          1           3
Row2      2          0           6
Row3      0          5           9
Row4      9          9           4
Row5      4          3           6
Row6      0          0           0

例如,在这里,我期望Row1和Row3在同一个组中(值不是相同的,而是“结构”相同),然后Row4和Row5将是另一个组,Row6是另一个组,Row2是另一个组。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-07 22:44:33

您可以使用反射来获取名为MyPropertyn的所有属性,其中n等于1,然后可以使用List of PropertyInfos来计算填充属性的位掩码,并根据该值进行分组。

首先,我使用了一些扩展方法:

代码语言:javascript
运行
复制
public static class StringExt {
    public static string Past(this string s, string starter) {
        var starterPos = s.IndexOf(starter);
        return starterPos == -1 ? String.Empty : s.Substring(starterPos + starter.Length);
    }
}

public static class NumericExt {
    public static int ToInt<T>(this T obj) => Convert.ToInt32(obj);

    public static int IntPow(this int x, int pow) {
        int ans = 1;

        while (pow != 0) {
            if ((pow & 0x1) == 1)
                ans *= x;
            x *= x;
            pow >>= 1;
        }
        return ans;
    }
}

现在您可以收集感兴趣的属性,排序,然后计算每一行的位掩码:

代码语言:javascript
运行
复制
var myPropInfos = typeof(COC).GetProperties()
                             .Where(pi => pi.Name.StartsWith("MyProperty"))
                             .OrderBy(pi => pi.Name.Past("MyProperty").ToInt()) // just in case properties aren't ordered
                             .ToList();
var GroupedFilters = src.Select(r => new { r, ValuedMask = myPropInfos.Select((pi, p) => pi.GetValue(r).ToString() != "0" ? 2.IntPow(p) : 0).Sum() })
                        .GroupBy(rm => rm.ValuedMask, rm => rm.r);

如果第一个属性没有以整数结尾,您将需要一个测试来以顺序处理该属性,或者,或者,(特别是如果属性没有全部以数字结尾),您可以不使用OrderBy并使用GetProperties返回的任何顺序--顺序并不重要。返回的答案是每个值属性组合的IGroupingKey是位掩码,显示哪些属性是值的。

如果您有超过31个属性,您应该切换到使用long并创建明显的LongPow扩展方法(2L.LongPow(p) : 0L)。

票数 1
EN

Stack Overflow用户

发布于 2019-05-07 20:41:47

你的桌子上有这样的东西:

代码语言:javascript
运行
复制
 Observable     Property      Value
     A             1            0
     A             2            1
     A             3            2
     B             1            0
     B             2            0
     B             3            1
     C             1            1
     C             2            2
     C             3            3

所有属性中值与0不同的所有组合:

代码语言:javascript
运行
复制
SELECT Observable
FROM Table
GROUP BY Observable
HAVING SUM(CASE WHEN VALUE = 0 THEN 1 ELSE 0 END) = 0

当只有一个具有值的属性,而其他属性为零时,所有组合:

代码语言:javascript
运行
复制
SELECT Observable
FROM Table
GROUP BY Observable
HAVING COUNT(CASE WHEN VALUE > 0 THEN 1 END) = 1

SQL演示

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56030025

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档