public class FlatList
{
public FlatList(IEnumerable<string> columns, List<List<object>> data, int totalCount)
{
Columns = columns;
Data = data;
TotalCount = totalCount;
}
public IEnumerable<string> Columns { get; }
public List<List<object>> Data { get; }
public int TotalCount { get; }
}
public class ColumnMetaData<T>
{
public string Name { get; set; }
public Func<T, object> ValueSelector { get; set; }
}
public class FlatListBuilder<T>
{
private readonly List<ColumnMetaData<T>> Columns = new();
public FlatListBuilder<T> AddColumn(string propertyName, Func<T, object> valueGetter)
{
var x = new ColumnMetaData<T>();
x.Name = propertyName;
x.ValueSelector = (y) =>
{
return valueGetter(y);
};
Columns.Add(x);
return this;
}
public FlatList Build(IEnumerable<T> items, int? totalCount = null)
{
var data = items.Select(x => Columns.Select(y => y.ValueSelector(x)).ToList()).ToList();
return new FlatList(Columns.Select(x => x.Name), data, totalCount ?? items.Count());
}
}
// usage:
var flatListBuilder = new FlatListBuilder<VmLookupItem>()
.AddColumn("id", x => x.Id)
.AddColumn("name", x => x.Description)
.AddColumn("additionalInfo", x => x.AdditionalInfo);
return flatListBuilder.Build(cachedItems);Convert data back in typescript:
export interface IListView {
columns: string[];
data: Array<any[]>;
}
export function mapListView<T>(listView: IListView): T[] {
const columns = listView.columns.map((name, i) => ({ index: i, name: name }));
return listView.data.map((row) => {
const item: any = {};
for (const { index, name } of columns)
item[name] = row[index];
return item as T;
});
}
async getAllDebtorArticles(debtorId: string): Promise<IDebtorArticle[]> {
const listView = await appDependencies.IRestApi.request(`api/article/debtor/${debtorId}`).getData<IListView>();
return mapListView<IDebtorArticle>(listView);
}
744000cookie-checkC# ListView/FlatList Builder