多列不区分大小写的组

dav*_*v_i 12 c# linq linq-to-sql

反正有没有做LINQ2SQL查询做类似的事情:

var result = source.GroupBy(a => new { a.Column1, a.Column2 });
Run Code Online (Sandbox Code Playgroud)

要么

var result = from s in source
             group s by new { s.Column1, s.Column2 } into c
             select new { Column1 = c.Key.Column1, Column2 = c.Key.Column2 };
Run Code Online (Sandbox Code Playgroud)

但忽略了分组列内容的情况?

Nav*_*hat 27

您可以传递StringComparer.InvariantCultureIgnoreCaseGroupBy扩展方法.

var result = source.GroupBy(a => new { a.Column1, a.Column2 }, 
                StringComparer.InvariantCultureIgnoreCase);
Run Code Online (Sandbox Code Playgroud)

或者你可以ToUpperInvariant按照Hamlet Hakobyan的建议在每个领域使用评论.我建议ToUpperInvariant还是ToUpper而非ToLower或者ToLowerInvariant因为它是对程序性比较的目的进行了优化.

  • `StringComparer`不能比较匿名类型的实例,只能比较字符串.需要一个新的比较器实现(见比尔B的答案) (8认同)

Bil*_*l B 6

我无法让NaveenBhat的解决方案工作,收到编译错误:

无法从用法中推断出方法'System.Linq.Enumerable.GroupBy(System.Collections.Generic.IEnumerable,System.Func,System.Collections.Generic.IEqualityComparer)'的类型参数.尝试显式指定类型参数.

为了使它工作,我发现最简单和最清楚的是定义一个新类来存储我的键列(GroupKey),然后是一个实现IEqualityComparer(KeyComparer)的单独类.然后我可以打电话

var result= source.GroupBy(r => new GroupKey(r), new KeyComparer());
Run Code Online (Sandbox Code Playgroud)

KeyComparer类确实将字符串与InvariantCultureIgnoreCase比较器进行比较,因此感谢NaveenBhat将我指向正确的方向.

我的课程的简化版本:

private class GroupKey
{
    public string Column1{ get; set; }
    public string Column2{ get; set; }

    public GroupKey(SourceObject r) {
        this.Column1 = r.Column1;
        this.Column2 = r.Column2;
    }
}

private class KeyComparer: IEqualityComparer<GroupKey>
{

    bool IEqualityComparer<GroupKey>.Equals(GroupKey x, GroupKey y)
    {
        if (!x.Column1.Equals(y.Column1,StringComparer.InvariantCultureIgnoreCase) return false;
        if (!x.Column2.Equals(y.Column2,StringComparer.InvariantCultureIgnoreCase) return false;
        return true;
        //my actual code is more complex than this, more columns to compare
        //and handles null strings, but you get the idea.
    }

    int IEqualityComparer<GroupKey>.GetHashCode(GroupKey obj)
    {
        return 0.GetHashCode() ; // forces calling Equals
        //Note, it would be more efficient to do something like
        //string hcode = Column1.ToLower() + Column2.ToLower();
        //return hcode.GetHashCode();
        //but my object is more complex than this simplified example

    }
}
Run Code Online (Sandbox Code Playgroud)