forked from ddrilling/AsbCloudServer
Merge branch 'master' of https://bitbucket.org/frolovng/asbcloudserver
This commit is contained in:
commit
31a33b243f
@ -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
|
||||
|
45
ConsoleApp1/AnalyzeResult.cs
Normal file
45
ConsoleApp1/AnalyzeResult.cs
Normal 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; }
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
namespace ConsoleApp1
|
||||
{
|
||||
public class Header
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public System.Type PropertyType { get; set; } = typeof(object);
|
||||
}
|
||||
}
|
@ -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
|
||||
|
8
DataTable/DataTable.csproj
Normal file
8
DataTable/DataTable.csproj
Normal 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
13
DataTable/Header.cs
Normal 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
91
DataTable/Program.cs
Normal 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}");
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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
87
DataTable/TableMapper.cs
Normal 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
24
DataTable/TestDto.cs
Normal 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; }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user