项目中在经常会对数据解析并做图标展示,数据获取的方式有很多(文本文件、api、数据库……),大多数情况下我们都会将数据转化为泛型类List或者DataTable两种数据类型并做处理,并绑定在UI界面做各种炫酷的展示,下面我们讲讲这泛型类List和DataTable两种数据源的数据处理吧。
指定列去重复数据
#region ①ToTable
DataView pDataView = new DataView ( vDataTable) ;
string [ ] pDistinctColumnName = { vTableColumnName, vTableColumnClass } ;
DataTable pTempDataViewTable = pDataView. ToTable ( true , pDistinctColumnName) ;
#endregion
使用GroupBy + FirstOrDefault函数
#region ② GroupBy + FirstOrDefault
DataTable dt_DistinctTable = vDataTable. AsEnumerable ( )
. Cast < DataRow > ( ) . Distinct ( )
. GroupBy ( p = > new {
Name = p. Field < string > ( vTableColumnName) ,
Class= p. Field < string > ( vTableColumnClass)
} )
. Select ( p = > p. FirstOrDefault ( ) )
. CopyToDataTable ( ) ;
#endregion
效果图 去重复前 去重复后
DataTable
转换为List<Model>
List< IGroupByModel> pDistinctDataRowsLamdaToLst = vDataTable. Rows. Cast < DataRow > ( )
. GroupBy ( dr = > new {
Name = dr. Field < string > ( vTableColumnName) ,
Class = dr. Field < string > ( vTableColumnClass)
} )
. Select ( x = > x. FirstOrDefault ( ) )
. AsEnumerable ( )
. Select ( p = > new IGroupByModel ( ) {
Name = p. Field < string > ( vTableColumnName) ,
Class = p. Field < string > ( vTableColumnClass)
} )
. ToList < IGroupByModel > ( ) ;
var result = from dt in vDataTable. AsEnumerable ( )
group dt by new {
Name = dt. Field < string > ( vTableColumnName) ,
Class = dt. Field < string > ( vTableColumnClass)
}
into temp
select new IGroupByModel ( )
{
Name = temp. Key. Name,
Class = temp. Key. Class,
} ;
List< IGroupByModel> pDistinctDataRowsLinqToLst = result. ToList < IGroupByModel > ( ) ;
分组后相同列数据用“,”
拼接
string pColumn2Value = string . Empty;
foreach ( GroupByModel pGroupByModelItem in pModelLst)
{
if ( string . IsNullOrEmpty ( pColumn2Value) )
{
pColumn2Value = pGroupByModelItem. Class == null ? ""
: pGroupByModelItem. Class. ToString ( ) ;
}
else
{
pColumn2Value + = pGroupByModelItem. Class == null ? ""
: "," + pGroupByModelItem. Class. ToString ( ) ;
}
}
string pColumn2Value = string . Empty;
pColumn2Value = pModelLst. Aggregate ( "" , ( a, b) = >
{
if ( ! string . IsNullOrEmpty ( b. Class) )
{
if ( a == "" )
{
return b. Class;
}
a + = "," + b. Class;
return a;
}
else
{
return a;
}
} ) ;
效果 聚合前 聚合后
结合MVVM
在WPF
的实现
public class GroupByModel
{
#region 字段、属性
public string Name { get ; set ; }
public string Class { get ; set ; }
#endregion
#region 私有方法
private static DataTable CreateCustomDataTable ( string pColumnNameOne, string pColumnNameTwo)
{
try
{
DataTable pDataTable = new DataTable ( ) ;
pDataTable. Columns. Add ( pColumnNameOne, typeof ( string ) ) ;
pDataTable. Columns. Add ( pColumnNameTwo, typeof ( string ) ) ;
for ( int i = 0 ; i < 3 ; i++ )
{
DataRow pDataRow = pDataTable. NewRow ( ) ;
pDataRow[ pColumnNameOne] = "Name" + i;
pDataRow[ pColumnNameTwo] = "Class" + i;
pDataTable. Rows. Add ( pDataRow) ;
}
for ( int i = 0 ; i < 3 ; i++ )
{
DataRow pDataRow = pDataTable. NewRow ( ) ;
pDataRow[ pColumnNameOne] = "Name" + i;
pDataRow[ pColumnNameTwo] = "Class" + i + i;
pDataTable. Rows. Add ( pDataRow) ;
}
for ( int i = 0 ; i < 6 ; i++ )
{
DataRow pDataRow = pDataTable. NewRow ( ) ;
pDataRow[ pColumnNameOne] = "Name" + i;
pDataRow[ pColumnNameTwo] = "Class" + i;
pDataTable. Rows. Add ( pDataRow) ;
}
return pDataTable;
}
catch ( Exception ex)
{
CommonBasic. Log. BlossLog. AddErrorLog ( ex) ;
return null ;
}
}
#region DataTable
private static DataTable GetMergeColumDataTable ( DataTable vDataTable, string vTableColumnName, string vTableColumnClass, string nameColumnOne, string nameColumnTwo, out int oDistinctCount)
{
oDistinctCount = 0 ;
try
{
if ( vDataTable == null || vDataTable. Rows. Count == 0 )
{
return null ;
}
DataTable pDataTable = new DataTable ( ) ;
pDataTable. Columns. Add ( nameColumnTwo, typeof ( string ) ) ;
pDataTable. Columns. Add ( nameColumnOne, typeof ( string ) ) ;
#region 去重复数据
#region ①ToTable
DataView pDataView = new DataView ( vDataTable) ;
string [ ] pDistinctColumnName = { vTableColumnName, vTableColumnClass } ;
DataTable pTempDataViewTable = pDataView. ToTable ( true , pDistinctColumnName) ;
#endregion
#region ② GroupBy + FirstOrDefault
DataTable dt_DistinctTable = vDataTable. AsEnumerable ( ) . Cast < DataRow > ( ) . Distinct ( ) . GroupBy ( p = > new { Name = p. Field < string > ( vTableColumnName) , Class= p. Field < string > ( vTableColumnClass) } ) . Select ( p = > p. FirstOrDefault ( ) ) . CopyToDataTable ( ) ;
#endregion
#endregion
#region 按列(vTableColumnName)分组
IEnumerable< IGrouping< string , DataRow> > pGroupDataTable = pTempDataViewTable. Rows. Cast < DataRow > ( ) . Distinct < DataRow > ( ) . GroupBy < DataRow , string > ( dr = > dr[ vTableColumnName] . ToString ( ) ) ;
foreach ( IGrouping< string , DataRow> pGroupDataTableRow in pGroupDataTable)
{
DataRow pDataRow = pDataTable. NewRow ( ) ;
pDataRow[ nameColumnOne] = pGroupDataTableRow. Key;
string pColumn2Value = string . Empty;
#region 相同Key值Value叠加方式一 http://www.bamn.cn/News/views/129
#endregion
#region 相同Key值Value叠加方式2
foreach ( DataRow pDataRowItem in pGroupDataTableRow)
{
if ( string . IsNullOrEmpty ( pColumn2Value) )
{
pColumn2Value = pDataRowItem[ vTableColumnClass] == null ? "" : pDataRowItem[ vTableColumnClass] . ToString ( ) ;
}
else
{
pColumn2Value + = pDataRowItem[ vTableColumnClass] == null ? "" : "," + pDataRowItem[ vTableColumnClass] . ToString ( ) ;
}
}
#endregion
pDataRow[ nameColumnTwo] = pColumn2Value;
pDataTable. Rows. Add ( pDataRow) ;
}
#endregion
#region 统计数量
object pObj = vDataTable? . AsEnumerable ( ) . Select ( r = > r[ vTableColumnClass] . ToString ( ) ) . Distinct ( ) . Count ( ) ;
oDistinctCount = Convert. ToInt32 ( pObj) ;
#endregion
return pDataTable;
}
catch ( Exception ex)
{
CommonBasic. Log. BlossLog. AddErrorLog ( ex) ;
return null ;
}
}
#endregion
#region List
private static List< GroupByModel> GetMergeColumDataTableToLst ( DataTable vDataTable, string vTableColumnName, string vTableColumnClass, out int oDistinctCount)
{
oDistinctCount = 0 ;
try
{
if ( vDataTable == null || vDataTable. Rows. Count == 0 )
{
return null ;
}
List< GroupByModel> pIGroupByModelLst = new List < GroupByModel > ( ) ;
#region 转化为Lis thttps://www.cnblogs.com/johnblogs/p/6006867.html
#region lamda 表达式写法(推荐)
List< GroupByModel> pDistinctDataRowsLamdaToLst = vDataTable. Rows. Cast < DataRow > ( )
. GroupBy ( dr = > new { Name = dr. Field < string > ( vTableColumnName) , Class = dr. Field < string > ( vTableColumnClass) } )
. Select ( x = > x. FirstOrDefault ( ) )
. AsEnumerable ( ) . Select ( p = > new GroupByModel ( ) { Name = p. Field < string > ( vTableColumnName) , Class = p. Field < string > ( vTableColumnClass) } ) . ToList < GroupByModel > ( ) ;
#endregion
#region Linq写法 最终编译器会把它转化为lamda表达式 https://www.cnblogs.com/hedianzhan/p/9010999.html
var result = from dt in vDataTable. AsEnumerable ( )
group dt by new { Name = dt. Field < string > ( vTableColumnName) , Class = dt. Field < string > ( vTableColumnClass) } into temp
select new GroupByModel ( )
{
Name = temp. Key. Name,
Class = temp. Key. Class,
} ;
List< GroupByModel> pDistinctDataRowsLinqToLst = result. ToList < GroupByModel > ( ) ;
#endregion
#endregion
#region 按列(vTableColumnName)分组
IEnumerable< IGrouping< string , GroupByModel> > pGroupByModelLst = pDistinctDataRowsLamdaToLst. Distinct ( ) . GroupBy < GroupByModel , string > ( p = > p. Name) ;
foreach ( IGrouping< string , GroupByModel> pModelLst in pGroupByModelLst)
{
GroupByModel pIGroupByModel = new GroupByModel ( ) ;
pIGroupByModel. Name = pModelLst. Key;
string pColumn2Value = string . Empty;
#region 相同Key值Value叠加方式一
pColumn2Value = pModelLst. Aggregate ( "" , ( a, b) = >
{
if ( ! string . IsNullOrEmpty ( b. Class) )
{
if ( a == "" )
{
return b. Class;
}
a + = "," + b. Class;
return a;
}
else
{
return a;
}
} ) ;
#endregion
#region 相同Key值Value叠加方式2
#endregion
pIGroupByModel. Class = pColumn2Value;
pIGroupByModelLst. Add ( pIGroupByModel) ;
}
#endregion
#region 统计数量
object pObj = vDataTable? . AsEnumerable ( ) . Select ( r = > r[ vTableColumnClass] . ToString ( ) ) . Distinct ( ) . Count ( ) ;
oDistinctCount = Convert. ToInt32 ( pObj) ;
#endregion
return pIGroupByModelLst;
}
catch ( Exception ex)
{
CommonBasic. Log. BlossLog. AddErrorLog ( ex) ;
return null ;
}
}
#endregion
#endregion
#region 对外接口方法
public static DataTable GetIGroupByModelTable ( out int oDistinctCount)
{
oDistinctCount = 0 ;
try
{
string pName = "Name" ;
string pClassName = "Class" ;
DataTable pDataTable = CreateCustomDataTable ( pName, pClassName) ;
string pOtherName = "姓名" ;
string pOtherClassName = "班级" ;
DataTable pDataTableResult = GetMergeColumDataTable ( pDataTable, pName, pClassName, pOtherName, pOtherClassName, out int ooDistinctCount) ;
oDistinctCount = ooDistinctCount;
return pDataTableResult;
}
catch ( Exception ex)
{
CommonBasic. Log. BlossLog. AddErrorLog ( ex) ;
return null ;
}
}
public static List< GroupByModel> GetIGroupByModelLst ( out int oDistinctCount)
{
oDistinctCount = 0 ;
try
{
string pName = "Name" ;
string pClassName = "Class" ;
DataTable pDataTable = CreateCustomDataTable ( pName, pClassName) ;
List< GroupByModel> pGroupByModelLst = GetMergeColumDataTableToLst ( pDataTable, pName, pClassName, out int ooDistinctCount) ;
oDistinctCount = ooDistinctCount;
return pGroupByModelLst;
}
catch ( Exception ex)
{
CommonBasic. Log. BlossLog. AddErrorLog ( ex) ;
return null ;
}
}
#endregion
}
public class GroupByViewModel : INotifyPropertyChanged
{
#region 字段属性
public DataTable _pDataTableLst { get ; set ; }
public DataTable pDataTableLst {
get
{
return _pDataTableLst;
}
set
{
if ( _pDataTableLst != value )
{
_pDataTableLst = value ;
OnNotifyPropertyChanged ( "pDataTableLst" ) ;
}
}
}
public List< GroupByModel> _pGroupByModelLst { get ; set ; }
public List< GroupByModel> pGroupByModelLst
{
get
{
return _pGroupByModelLst;
}
set
{
if ( _pGroupByModelLst != value )
{
_pGroupByModelLst = value ;
OnNotifyPropertyChanged ( "pGroupByModelLst" ) ;
}
}
}
public Int32 _pDataTableCount { get ; set ; }
public Int32 pDataTableCount
{
get
{
return _pDataTableCount;
}
set
{
if ( _pDataTableCount != value )
{
_pDataTableCount = value ;
OnNotifyPropertyChanged ( "pDataTableCount" ) ;
}
}
}
#endregion
public GroupByViewModel ( )
{
pDataTableLst = GroupByModel. GetIGroupByModelTable ( out int oDistinctCount) ;
pGroupByModelLst = GroupByModel. GetIGroupByModelLst ( out int oDistinctCount2) ;
}
#region INotifyPropertyChanged接口方法
public virtual event PropertyChangedEventHandler PropertyChanged;
public virtual void OnNotifyPropertyChanged ( string propertyName)
{
PropertyChanged? . Invoke ( this , new PropertyChangedEventArgs ( propertyName) ) ;
}
#endregion
}
public partial class IGroupByStyleView : Window
{
public IGroupByStyleView ( )
{
InitializeComponent ( ) ;
this . DataContext = new GroupByViewModel ( ) ;
}
}
参考