This commit is contained in:
KharchenkoVV 2021-06-07 16:31:40 +05:00
commit 31a33b243f
11 changed files with 312 additions and 78 deletions

View File

@ -13,6 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApp1", "ConsoleApp1\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AsbCloudDb", "AsbCloudDb\AsbCloudDb.csproj", "{40FBD29B-724B-4496-B5D9-1A5D14102456}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataTable", "DataTable\DataTable.csproj", "{28AD7CD5-17A0-448C-8C16-A34AE5DE40FB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -39,6 +41,10 @@ Global
{40FBD29B-724B-4496-B5D9-1A5D14102456}.Debug|Any CPU.Build.0 = Debug|Any CPU
{40FBD29B-724B-4496-B5D9-1A5D14102456}.Release|Any CPU.ActiveCfg = Release|Any CPU
{40FBD29B-724B-4496-B5D9-1A5D14102456}.Release|Any CPU.Build.0 = Release|Any CPU
{28AD7CD5-17A0-448C-8C16-A34AE5DE40FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{28AD7CD5-17A0-448C-8C16-A34AE5DE40FB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{28AD7CD5-17A0-448C-8C16-A34AE5DE40FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{28AD7CD5-17A0-448C-8C16-A34AE5DE40FB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
public enum WellDepthState {Idle, Increase }
public enum BitDepthState {Idle, Increase, Decrease, OnSurface}
public enum BlockState {Idle, Increase, Decrease}
public enum RotorState {Inactive, Active}
public enum PressureState { Inactive, Active }
public enum HookWeightState { Idle, None }
public enum DrillingOperation {
Unknown,
RotorDrilling,
SlideDrilling,
TrippingOutReaming,
TrippingInReaming,
TrippingOutCirculating,
TrippingInCirculating,
TrippingOut,
TrippingIn,
Circulating,
CirculatingRotating,
Hold,
Static,
Rotating,
OnTheSurface,
}
public class AnalyzeResult
{
public int Id { get; set; }
public DateTime Date { get; set; }
public WellDepthState WellDepthState { get; set; }
public BitDepthState BitDepthState { get; set; }
public BlockState BlockState { get; set; }
public RotorState RotorState { get; set; }
public PressureState PressureState { get; set; }
public HookWeightState HookWeightState { get; set; }
public DrillingOperation DrillingOperation { get; set; }
}
}

View File

@ -1,8 +0,0 @@
namespace ConsoleApp1
{
public class Header
{
public string Name { get; set; }
public System.Type PropertyType { get; set; } = typeof(object);
}
}

View File

@ -20,21 +20,21 @@ namespace ConsoleApp1
{
static void Main(string[] args)
{
var options = new DbContextOptionsBuilder<AsbCloudDbContext>()
.UseNpgsql("Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True")
.Options;
var context = new AsbCloudDbContext(options);
//var options = new DbContextOptionsBuilder<AsbCloudDbContext>()
// .UseNpgsql("Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True")
// .Options;
//var context = new AsbCloudDbContext(options);
var e = new Event
{
IdEvent = 1,
IdTelemetry = 1,
IdCategory = 1,
MessageTemplate = "template",
};
//var e = new Event
//{
// IdEvent = 1,
// IdTelemetry = 1,
// IdCategory = 1,
// MessageTemplate = "template",
//};
context.Events.Update(e).State = EntityState.Added;
context.SaveChanges();
//context.Events.Update(e).State = EntityState.Added;
//context.SaveChanges();
//var table = new Table

View File

@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
</Project>

13
DataTable/Header.cs Normal file
View File

@ -0,0 +1,13 @@
using System;
namespace DataTable
{
[Serializable]
public class Header
{
public string Name { get; set; }
public string Desctiption { get; set; }
//public System.Type ColumnType { get; set; } = typeof(object);
public string ColumnType { get; set; }
}
}

91
DataTable/Program.cs Normal file
View File

@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text.Json;
namespace DataTable
{
class Program
{
static void Main(string[] args)
{
var listDtos = new List<TestDto>(100);
/* *** Size of TestDto calc ***
*
* ** data binary size (Not implemented) **
* Date : DateTime : 4b
* Mode : int32? : 4b
* User : string : 2-64b
* WellDepth : double? : 8b
* TOTAL data size = 18-80b
*
* ** header binary size (Not implemented) **
*
*DateTime : len("DateTime") + 2 + len("Date") + 2 = 16b
* Mode : 14b
* User : 14b
* WellDepth : 20b
* columnsCount : 2b
* TOTAL header size = 66b
*
* ** json as tab **
*
* header size: 137b
* json row size: 63b
*
* total for 1 record : 200b
* total for 2 records : 263b
*
* ** json as list **
*
* Raw listItem size: 175b
* total for 2 records : 350b
*
* ** example 100 records **
* tabJsonBytes: 6602
* listJsonBytes: 9628
* tabBinBytes: 7765 (by dangerous BinaryFormatter)
* listBinBytes: 4366 (by dangerous BinaryFormatter)
*/
for (int i = 0; i < 100; i++)
listDtos.Add(new TestDto{
Date = DateTime.Now.AddSeconds(i),
Mode = 1,
WellDepth = i * Math.PI
});
var tMapper = new TableMapper<TestDto>();
var tab = tMapper.MakeTable(listDtos);
var e = tMapper.AsEnumerable(tab);
var tabJson = JsonSerializer.Serialize(tab);
var listJson = JsonSerializer.Serialize(listDtos);
var tabJsonBytes = JsonSerializer.SerializeToUtf8Bytes(tab);
var listJsonBytes = JsonSerializer.SerializeToUtf8Bytes(listDtos);
var formatter = new BinaryFormatter();
var mem = new MemoryStream();
formatter.Serialize(mem, tab);
var tabBinBytes = new byte[mem.Length];
Array.Copy(mem.GetBuffer(), tabBinBytes, mem.Length);
mem = new MemoryStream();
formatter.Serialize(mem, listDtos);
var listBinBytes = new byte[mem.Length];
Array.Copy(mem.GetBuffer(), listBinBytes, mem.Length);
Console.WriteLine($"tabJsonBytes:{tabJsonBytes.Length}");
Console.WriteLine($"listJsonBytes:{listJsonBytes.Length}");
Console.WriteLine($"tabBinBytes:{tabBinBytes.Length}");
Console.WriteLine($"listBinBytes:{listBinBytes.Length}");
}
}
}

View File

@ -1,61 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.ComponentModel;
namespace ConsoleApp1
namespace DataTable
{
// для работы с таблицами
public class TableMapper<T>
{
private readonly Dictionary<string, PropertyHelper> props;
public TableMapper()
{
var props = typeof(T).GetProperties();
this.props = new Dictionary<string, PropertyHelper>(props.Length);
foreach (var prop in props)
{
var helper = new PropertyHelper(prop);
this.props.Add(helper.Id, helper);
}
}
public int UpdateObjectFromTable(ref T obj, Table table, int rowIndex)
{
var updatesCount = 0;
if (table.Rows.Count() <= rowIndex)
return 0;
var row = table.Rows.ElementAt(rowIndex);
var headerIndex = 0;
foreach (var header in table.Headers)
{
var headerId = PropertyHelper.MakeIdentity(header.PropertyType.Name, header.Name);
if (props.ContainsKey(headerId))
{
props[headerId].Set(obj, row.ElementAt(headerIndex));
updatesCount++;
}
headerIndex++;
}
return updatesCount;
}
}
/// <summary>
/// Ускоренный обработчик свойства
/// </summary>
class PropertyHelper
{
delegate void SetterDelegate(object instanse, object[] values);
delegate object GetterDelegate(object instanse);
public string PropertyName { get; }
public string PropertyDesctiption { get; }
public Type PropertyType { get; }
public string Id { get; }
SetterDelegate Setter { get; }
GetterDelegate Getter { get; }
public PropertyHelper(PropertyInfo property)
{
PropertyName = property.Name;
PropertyType = property.PropertyType;
Id = MakeIdentity(property.PropertyType.Name, property.Name);
PropertyDesctiption = GetDescription(property);
var setter = property.SetMethod;
var getter = property.GetMethod;
@ -65,21 +37,15 @@ namespace ConsoleApp1
var argumentExpressions = new List<Expression> { Expression.Convert(Expression.ArrayIndex(argumentsExpression, Expression.Constant(0)), PropertyType) };
var callExpression = Expression.Call(Expression.Convert(instanceExpression, setter.ReflectedType), setter, argumentExpressions);
Setter = Expression.Lambda<SetterDelegate>(callExpression, instanceExpression, argumentsExpression).Compile();
callExpression = Expression.Call(Expression.Convert(instanceExpression, getter.ReflectedType), getter);
Getter = Expression.Lambda<GetterDelegate>(Expression.Convert(callExpression, typeof(object)), instanceExpression).Compile();
}
public string PropertyName { get; }
public Type PropertyType { get; }
public string Id { get; }
delegate void SetterDelegate(object instanse, object[] values);
delegate object GetterDelegate(object instanse);
SetterDelegate Setter { get; }
GetterDelegate Getter { get; }
private string GetDescription(PropertyInfo property)
{
var descriptionAttr = property.GetCustomAttribute<DescriptionAttribute>();
return descriptionAttr?.Description ?? string.Empty;
}
void SetValues(object instance, params object[] values)
=> Setter(instance, values);
@ -90,6 +56,7 @@ namespace ConsoleApp1
public object Get(object instance)
=> Getter(instance);
public static string MakeIdentity(string propertyTypeName, string propertyName) => $"{propertyTypeName}_{propertyName}".ToLower();
public static string MakeIdentity(string propertyTypeName, string propertyName)
=> $"{propertyTypeName}_{propertyName}".ToLower();
}
}

View File

@ -1,13 +1,14 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
namespace ConsoleApp1
namespace DataTable
{
[Serializable]
public class Table
{
public IEnumerable<Header> Headers { get; set; }
public IEnumerable<IEnumerable<object>> Rows { get; set; }
}
}

87
DataTable/TableMapper.cs Normal file
View File

@ -0,0 +1,87 @@
using System.Collections.Generic;
using System.Linq;
namespace DataTable
{
public class TableMapper<T>
where T: new()
{
private readonly Dictionary<string, PropertyHelper> props;
public TableMapper()
{
var props = typeof(T).GetProperties();
this.props = new Dictionary<string, PropertyHelper>(props.Length);
foreach (var prop in props)
{
var helper = new PropertyHelper(prop);
this.props.Add(helper.Id, helper);
}
}
public IEnumerable<T> AsEnumerable(Table table)
{
if ((table?.Headers is null) ||
(table?.Rows is null) ||
(!table.Headers.Any()) ||
(!table.Rows.Any()) ||
(!props.Any()) )
yield break;
var headerIdToProp = new Dictionary<int, PropertyHelper>(props.Count);
foreach(var (_, propHelper) in props)
for(var i = 0; i < table.Headers.Count(); i++)
{
var header = table.Headers.ElementAt(i);
var columnType = System.Type.GetType(header.ColumnType);
if (columnType.IsAssignableTo(propHelper.PropertyType) &&
((header.Name == propHelper.PropertyName) ||
(header.Name.ToLower() == propHelper.PropertyName.ToLower())))
headerIdToProp.Add(i, propHelper);
}
if (!headerIdToProp.Any())
yield break;
foreach (var row in table.Rows)
{
var obj = new T();
foreach (var (i, propHelper) in headerIdToProp)
propHelper.Set(obj, row.ElementAt(i));
yield return obj;
}
yield break;
}
public Table MakeTable(IEnumerable<T> data)
{
var table = new Table();
table.Headers = props.Select(pair => new Header
{
Name = pair.Value.PropertyName,
ColumnType = pair.Value.PropertyType.Name,
}).ToArray();
var rows = new List<List<object>>(data.Count());
foreach(var dataItem in data)
rows.Add(MakeRow(dataItem));
table.Rows = rows;
return table;
}
private List<object> MakeRow(T dataItem)
{
var colunms = new List<object>(props.Count);
foreach (var (_, propHelper) in props)
{
var propValue = propHelper.Get(dataItem);
colunms.Add(propValue);
}
return colunms;
}
}
}

24
DataTable/TestDto.cs Normal file
View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataTable
{
[Serializable]
public class TestDto
{
[Description("Дата")]
public DateTime Date { get; set; } = DateTime.Now;
public int? Mode { get; set; }
[Description("Пользователь")]
public string User { get; set; }
[Description("Глубина забоя")]
public double? WellDepth { get; set; }
}
}