C# 将每个空值作为一个组的Linq GroupBy
我有一个具有可为空的int属性“GroupId”的对象 有了这个对象的列表,我想在这个“GroupId”上做一个GroupBy。但是如果我这样做,所有的空值将组成一个组 例如: 对象1:GroupId:NULL 对象2:GroupId:NULL 对象3:GroupId:1 对象4:GroupId:1 对象5:GroupId:2C# 将每个空值作为一个组的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
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>());