我有一张名为 Languagemaster 的表格,其记录低于记录
language keyName keyValue
English City AA
Swedish City AAswedish
German City AAger
Chines City AAchines
French City AAfr
Spanish City AAspanish
如何将 Languagemaster 表转换为下表
keyName English Swedish German Chines French Spanish
City AA AAswedish AAger AAchines AAfr AAspanish
请告诉我如何在SOL和LinQ中编写查询。
答案 0 :(得分:23)
更新:我创建了以下通用方法,可以从任何集合构建数据透视表
public static DataTable ToPivotTable<T, TColumn, TRow, TData>(
this IEnumerable<T> source,
Func<T, TColumn> columnSelector,
Expression<Func<T, TRow>> rowSelector,
Func<IEnumerable<T>, TData> dataSelector)
{
DataTable table = new DataTable();
var rowName = ((MemberExpression)rowSelector.Body).Member.Name;
table.Columns.Add(new DataColumn(rowName));
var columns = source.Select(columnSelector).Distinct();
foreach (var column in columns)
table.Columns.Add(new DataColumn(column.ToString()));
var rows = source.GroupBy(rowSelector.Compile())
.Select(rowGroup => new {
Key = rowGroup.Key,
Values = columns.GroupJoin(
rowGroup,
c => c,
r => columnSelector(r),
(c, columnGroup) => dataSelector(columnGroup))
});
foreach (var row in rows) {
var dataRow = table.NewRow();
var items = row.Values.Cast<object>().ToList();
items.Insert(0, row.Key);
dataRow.ItemArray = items.ToArray();
table.Rows.Add(dataRow);
}
return table;
}
用法:
var table = Languagemaster.ToPivotTable(
item => item.language,
item => item.keyName,
items => items.Any() ? items.First().keyValue : null);
它有三个参数:
keyValue
属性。但它可能是项目计数items => items.Count()
或其他任何内容。结果:
原始回答:
此查询将返回您的数据的数据透视。查询中的每个项目都有Name
(即示例中的“城市”)和值列表 - 每个数据透视列的一个值(即,对于每种语言,我们将使用包含语言名称Column
的值和Value
)
var languages = Languagemaster.Select(x => x.language).Distinct();
var query = from r in Languagemaster
group r by r.keyName into nameGroup
select new {
Name = nameGroup.Key,
Values = from lang in languages
join ng in nameGroup
on lang equals ng.language into languageGroup
select new {
Column = lang,
Value = languageGroup.Any() ?
languageGroup.First().keyValue : null
}
};
如何从此查询构建数据表
DataTable table = new DataTable();
table.Columns.Add("keyName"); // first column
foreach (var language in languages)
table.Columns.Add(language); // columns for each language
foreach (var key in query)
{
var row = table.NewRow();
var items = key.Values.Select(v => v.Value).ToList(); // data for columns
items.Insert(0, key.Name); // data for first column
row.ItemArray = items.ToArray();
table.Rows.Add(row);
}
答案 1 :(得分:0)
这是一个基于多列对数据进行分组的代码。
$(window).on('scroll', function(event) {
var scrollValue = $(window).scrollTop();
if ( scrollValue > 70) {
$('.navbar-sticky').addClass('fixed-top');
}else{
$('.navbar-sticky').removeClass('fixed-top');
}
});
答案 2 :(得分:0)
public static DataTable XToPivotTable<T, TColumn, TRow, TData>(this IEnumerable<T> source, Func<T, TColumn> columnSelector, Expression<Func<T, TRow>> rowSelector, Func<IEnumerable<T>, TData> dataSelector) {
DataTable table = new DataTable();
if (rowSelector.Body is NewExpression) {
var rowNames = ((NewExpression)rowSelector.Body).Members.ToList();
rowNames.ForEach(s => table.Columns.Add(new DataColumn(s.Name, s.DeclaringType.GetProperty(s.Name).PropertyType)));
} else {
var rowName = ((MemberExpression)rowSelector.Body).Member;
table.Columns.Add(new DataColumn(rowName.Name, rowName.DeclaringType.GetProperty(rowName.Name).PropertyType));
}
var columns = source.Select(columnSelector).Distinct();
foreach (var column in columns)
table.Columns.Add(new DataColumn(column.ToString()));
var rows = source.GroupBy(rowSelector.Compile())
.Select(rg => new {
rg.Key,
Values = columns.GroupJoin(rg, c => c, r => columnSelector(r), (c, cg) => dataSelector(cg))
});
foreach (var row in rows) {
var dataRow = table.NewRow();
var items = TypeDescriptor.GetProperties(typeof(TRow)).Cast<PropertyDescriptor>().Select(s => s.GetValue(row.Key)).ToList();
items.AddRange(row.Values.Cast<dynamic>());
dataRow.ItemArray = items.ToArray();
table.Rows.Add(dataRow);
}
return table;
}