112 lines
6.4 KiB
C#
112 lines
6.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
|
|
namespace Elwig.Models.Dtos {
|
|
public class DataTable<T> {
|
|
|
|
public string Name { get; set; }
|
|
public string FullName { get; set; }
|
|
public string? Subtitle { get; set; }
|
|
public IEnumerable<(string? Name, IEnumerable<T> Rows)> Sections { get; private set; }
|
|
public IEnumerable<T> Rows => Sections.SelectMany(s => s.Rows);
|
|
public int RowNum => Rows.Count();
|
|
public int ColNum => ColumnNames.Count();
|
|
|
|
public IEnumerable<(string Name, Type? Type)> ColumnDefs => _map.Select(m => (m.Name, m.PInfo?.PropertyType ?? m.FInfo?.FieldType));
|
|
public IEnumerable<string> ColumnNames => ColumnDefs.Select(m => m.Name);
|
|
public IEnumerable<Type?> ColumnTypes => ColumnDefs.Select(m => m.Type);
|
|
public IEnumerable<Type?> ColumnFlatTypes { get; private set; }
|
|
public IEnumerable<int> ColumnSpans { get; private set; }
|
|
public IEnumerable<int?> ColumnWidths { get; private set; }
|
|
public IEnumerable<string?[]> ColumnUnits { get; private set; }
|
|
|
|
private readonly PropertyInfo[] _properties;
|
|
private readonly FieldInfo[] _fields;
|
|
private readonly (string Name, PropertyInfo? PInfo, FieldInfo? FInfo)[] _map;
|
|
|
|
public DataTable(string name, string fullName, string subtitle, IEnumerable<(string? Name, IEnumerable<T> Rows)> sections, IEnumerable<(string Property, string Name, string? Unit, int? Width)>? colNames = null) :
|
|
this(name, fullName, sections, colNames) {
|
|
Subtitle = subtitle;
|
|
}
|
|
|
|
public DataTable(string name, string fullName, string subtitle, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit, int? Width)>? colNames = null) :
|
|
this(name, fullName, subtitle, [(null, rows)], colNames) {
|
|
}
|
|
|
|
public DataTable(string name, string fullName, IEnumerable<(string? Name, IEnumerable<T> Rows)> sections, IEnumerable<(string Property, string Name, string? Unit, int? Width)>? colNames = null) {
|
|
_fields = typeof(T).GetFields();
|
|
_properties = typeof(T).GetProperties();
|
|
colNames ??= [.. _properties.Select(p => p.Name).Union(_fields.Select(f => f.Name)).Select(i => (i, i, (string?)null, (int?)null))];
|
|
_map = [.. colNames.Select(n => (n.Name, _properties.FirstOrDefault(p => p?.Name == n.Property, null), _fields.FirstOrDefault(f => f?.Name == n.Property, null)))];
|
|
Name = name;
|
|
FullName = fullName;
|
|
Sections = sections;
|
|
ColumnFlatTypes = [.. ColumnTypes.SelectMany(type => {
|
|
var elType = type?.GetElementType();
|
|
return type != null && type.IsValueType && type.Name.StartsWith("ValueTuple") ? type.GetFields().Select(f => (Type?)f.FieldType) :
|
|
type != null && elType != null && type.IsArray && elType.IsValueType && elType.Name.StartsWith("ValueTuple") ? elType.GetFields().Select(f => (Type?)f.FieldType) :
|
|
[type];
|
|
})];
|
|
ColumnSpans = [.. ColumnTypes.Select(type => {
|
|
var elType = type?.GetElementType();
|
|
return type != null && type.IsValueType && type.Name.StartsWith("ValueTuple") ? type.GetFields().Length :
|
|
type != null && elType != null && type.IsArray && elType.IsValueType && elType.Name.StartsWith("ValueTuple") ? elType.GetFields().Length :
|
|
1;
|
|
})];
|
|
ColumnWidths = [.. colNames.Select(c => c.Width)];
|
|
ColumnUnits = [.. colNames.Select(c => c.Unit?.Split("|").Select(p => p.Length == 0 ? null : p).ToArray() ?? [])];
|
|
}
|
|
|
|
public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit, int? Width)>? colNames = null) :
|
|
this(name, fullName, [(null, rows)], colNames) {
|
|
}
|
|
|
|
public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit)>? colNames = null) :
|
|
this(name, fullName, rows, colNames?.Select(c => (c.Property, c.Name, c.Unit, (int?)null))) {
|
|
}
|
|
|
|
public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit, int Width)>? colNames = null) :
|
|
this(name, fullName, rows, colNames?.Select(c => (c.Property, c.Name, c.Unit, (int?)c.Width))) {
|
|
}
|
|
|
|
public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit, int? Width)>? colNames = null) :
|
|
this(name, name, rows, colNames) {
|
|
}
|
|
|
|
public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit)>? colNames = null) :
|
|
this(name, name, rows, colNames) {
|
|
}
|
|
|
|
public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit, int Width)>? colNames = null) :
|
|
this(name, name, rows, colNames) {
|
|
}
|
|
|
|
public DataTable(string name, string fullName, IEnumerable<(string? Name, IEnumerable<T> Rows)> sections, IEnumerable<(string Property, string Name, string? Unit)>? colNames = null) :
|
|
this(name, fullName, sections, colNames?.Select(c => (c.Property, c.Name, c.Unit, (int?)null))) {
|
|
}
|
|
|
|
public DataTable(string name, string fullName, IEnumerable<(string? Name, IEnumerable<T> Rows)> sections, IEnumerable<(string Property, string Name, string? Unit, int Width)>? colNames = null) :
|
|
this(name, fullName, sections, colNames?.Select(c => (c.Property, c.Name, c.Unit, (int?)c.Width))) {
|
|
}
|
|
|
|
protected IEnumerable<(string Name, object? Value)> GetNamedRowValues(T row) {
|
|
return _map.Select(i => (i.Name, i.PInfo?.GetValue(row) ?? i.FInfo?.GetValue(row)));
|
|
}
|
|
|
|
protected IEnumerable<object?> GetRowValues(T row) {
|
|
return GetNamedRowValues(row).Select(i => i.Value);
|
|
}
|
|
|
|
public IEnumerable<(string? Name, IEnumerable<IEnumerable<object?>> Rows)> GetData() {
|
|
return Sections.Select(s => (s.Name, s.Rows.Select(GetRowValues)));
|
|
}
|
|
|
|
public IEnumerable<(string? Name, IEnumerable<IEnumerable<(string Name, object? Value)>> Rows)> GetNamedData() {
|
|
return Sections.Select(s => (s.Name, s.Rows.Select(GetNamedRowValues)));
|
|
}
|
|
}
|
|
}
|