Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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 GroupBy_C#_Linq_Group By - Fatal编程技术网

C# 将每个空值作为一个组的Linq GroupBy

C# 将每个空值作为一个组的Linq GroupBy,c#,linq,group-by,C#,Linq,Group By,我有一个具有可为空的int属性“GroupId”的对象 有了这个对象的列表,我想在这个“GroupId”上做一个GroupBy。但是如果我这样做,所有的空值将组成一个组 例如: 对象1:GroupId:NULL 对象2:GroupId:NULL 对象3:GroupId:1 对象4:GroupId:1 对象5:GroupId:2 MyList.GroupBy(f => f.GroupId, key => new {Object = key}); 对象6:GroupId:2 MyLis

我有一个具有可为空的int属性“GroupId”的对象

有了这个对象的列表,我想在这个“GroupId”上做一个GroupBy。但是如果我这样做,所有的空值将组成一个组

例如:

对象1:GroupId:NULL

对象2:GroupId:NULL

对象3:GroupId:1

对象4:GroupId:1

对象5:GroupId:2

MyList.GroupBy(f => f.GroupId, key => new {Object = key});
对象6:GroupId:2

MyList.GroupBy(f => f.GroupId, key => new {Object = key});
我将得到3组


我怎样才能得到4组呢?每个空值对应一组…

这可能是最短的解决方案:

var grouped = MyList.GroupBy(f => f.GroupId != null ? (object)f.GroupId : new object(), key => new { Object = key });
请注意,组的“键”将为
对象类型。对于
null
元素,我创建了一个新的“空”对象
。对象的相等比较器将使它们完全不同。对于非空数字,我只是将它们框在一个对象中。装箱整数保持相等运算符。因此:

new object().Equals(new object()) == false // always

更正确的解决方案是实现
IEqualityComparer


无需装箱即可使用的通用比较器

public class NullableComparer<T> : IEqualityComparer<T?>
        where T : struct
{
    public bool Equals(T? x, T? y)
    {
        if (x == null || y == null)
        {
            return false;
        }

        return x.Equals(y);
    }

    public int GetHashCode(T? obj)
    {
        return obj.GetHashCode();
    }
}
公共类NullableComparer:IEqualityComparer
其中T:struct
{
公共布尔等于(T?x,T?y)
{
如果(x==null | | y==null)
{
返回false;
}
返回x等于(y);
}
公共int GetHashCode(T?obj)
{
返回obj.GetHashCode();
}
}
然后,您可以像这样使用它:

// where GroupId as a nullable Guid 
var grouped = MyList.GroupBy(f => f.GroupId, new NullableComparer<Guid>());
//其中GroupId作为可为空的Guid
var grouped=MyList.GroupBy(f=>f.GroupId,新的NullableComparer());

(使用not null筛选,然后应用group by group ID)union(使用null筛选,然后将group by应用于主键)。@JenishRabadiya注意,
GroupBy
维护元素/组的顺序,而您的解决方案将破坏顺序。@xanatos-hmm。。您是正确的。
(对象)1==(对象)1
始终为false
(object)==(object)
是引用等式,它不调用
object.Equals
。它工作正常,但列表是匿名列表,有没有办法将列表作为对象的模型或实体类型来拉?@MdAslam如果使用EF/EF Core,则是另一个问题。。。
var grouped2 = MyList.GroupBy(f => f.GroupId, key => new { Object = key }, new MyComparer());
public class NullableComparer<T> : IEqualityComparer<T?>
        where T : struct
{
    public bool Equals(T? x, T? y)
    {
        if (x == null || y == null)
        {
            return false;
        }

        return x.Equals(y);
    }

    public int GetHashCode(T? obj)
    {
        return obj.GetHashCode();
    }
}
// where GroupId as a nullable Guid 
var grouped = MyList.GroupBy(f => f.GroupId, new NullableComparer<Guid>());