DD.WellWorkover.Cloud/AsbCloudDb/Model/AsbCloudDbContext.cs
2021-07-21 15:29:19 +05:00

322 lines
15 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
#nullable disable
namespace AsbCloudDb.Model
{
//Scaffold-DbContext "Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True" Npgsql.EntityFrameworkCore.PostgreSQL -OutputDir Model -DataAnnotations
public partial class AsbCloudDbContext : DbContext, IAsbCloudDbContext
{
//private readonly string connectionString;
public virtual DbSet<Cluster> Clusters { get; set; }
public virtual DbSet<Company> Companies { get; set; }
public virtual DbSet<DataSaubBase> DataSaubBases { get; set; }
public virtual DbSet<Deposit> Deposits { get; set; }
public virtual DbSet<Event> Events { get; set; }
public virtual DbSet<Message> Messages { get; set; }
public virtual DbSet<Telemetry> Telemetries { get; set; }
public virtual DbSet<TelemetryUser> TelemetryUsers { get; set; }
public virtual DbSet<User> Users { get; set; }
public virtual DbSet<UserRole> UserRoles { get; set; }
public virtual DbSet<Well> Wells { get; set; }
public virtual DbSet<Report> Reports { get; set; }
public virtual DbSet<Operation> Operations { get; set; }
public virtual DbSet<TelemetryAnalysis> TelemetryAnalysis { get; set; }
public virtual DbSet<WellSection> SectionAnalysis { get; set; }
public virtual DbSet<WellType> WellTypes { get; set; }
//public AsbCloudDbContext(string connectionString = "Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True")
//{
// this.connectionString = connectionString;
// Database.EnsureCreated();
//}
public AsbCloudDbContext(DbContextOptions<AsbCloudDbContext> options)
: base(options)
{
Database.EnsureCreated();
}
//protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
//{
// if (!optionsBuilder.IsConfigured)
// {
// optionsBuilder.UseNpgsql(connectionString);
// }
//}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasPostgresExtension("adminpack")
.HasAnnotation("Relational:Collation", "Russian_Russia.1251");
modelBuilder.Entity<Cluster>(entity =>
{
entity.HasOne(d => d.Deposit)
.WithMany(p => p.Clusters)
.HasForeignKey(d => d.IdDeposit)
.HasConstraintName("t_cluster_t_deposit_id_fk");
});
modelBuilder.Entity<DataSaubBase>(entity =>
{
entity.HasOne(d => d.Telemetry)
.WithMany(p => p.DataSaubBases)
.HasForeignKey(d => d.IdTelemetry)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("t_data_saub_base_t_telemetry_id_fk");
});
modelBuilder.Entity<Message>(entity =>
{
entity.HasOne(d => d.Telemetry)
.WithMany(p => p.Messages)
.HasForeignKey(d => d.IdTelemetry)
.HasConstraintName("t_messages_t_telemetry_id_fk");
});
modelBuilder.Entity<TelemetryUser>(entity =>
{
entity.HasKey(nameof(TelemetryUser.IdTelemetry), nameof(TelemetryUser.IdUser));
entity.HasOne(d => d.Telemetry)
.WithMany(p => p.Users)
.HasForeignKey(d => d.IdTelemetry)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("t_telemetry_user_t_telemetry_id_fk");
});
modelBuilder.Entity<TelemetryAnalysis>(entity =>
{
entity.HasOne(d => d.Telemetry)
.WithMany(p => p.Analysis)
.HasForeignKey(d => d.IdTelemetry)
.HasConstraintName("t_analysis_t_telemetry_id_fk");
entity.HasOne(d => d.Operation)
.WithMany(p => p.Analysis)
.HasForeignKey(d => d.IdOperation)
.OnDelete(DeleteBehavior.SetNull)
.HasConstraintName("t_analysis_t_operation_id_fk");
});
modelBuilder.Entity<Event>(entity =>
{
entity.HasKey(nameof(Event.IdTelemetry), nameof(Event.IdEvent));
entity.HasOne(d => d.Telemetry)
.WithMany(p => p.Events)
.HasForeignKey(d => d.IdTelemetry)
.HasConstraintName("t_event_t_telemetry_id_fk");
});
modelBuilder.Entity<UserRole>(entity =>
{
entity.HasData(new List<UserRole>{
new UserRole{ Id = 1, Caption = "Администратор", },
});
});
modelBuilder.Entity<CompanyType>(entity =>
{
entity.HasData(new List<CompanyType>{
new CompanyType{ Id = 1, Caption = "Недрапользователь", },
new CompanyType{ Id = 2, Caption = "Буровой подрядчик", },
new CompanyType{ Id = 3, Caption = "Сервис автоматизации бурения", },
});
});
modelBuilder.Entity<Company>(entity =>
{
entity.HasData(new List<Company>{
new Company{ Id = 1, Caption = "\"ООО\" АСБ", IdCompanyType = 3},
});
});
modelBuilder.Entity<User>(entity =>
{
entity.HasOne(d => d.Company)
.WithMany(p => p.Users)
.HasForeignKey(d => d.IdCompany)
.HasConstraintName("t_user_t_company_id_fk");
entity.HasIndex(d => d.Login)
.IsUnique();
entity.HasData(new List<User>{
new User{
Id = 1,
IdCompany = 1,
IdRole = 1,
Level = int.MaxValue,
Login = "dev",
PasswordHash = "Vlcj|4fa529103dde7ff72cfe76185f344d4aa87931f8e1b2044e8a7739947c3d18923464eaad93843e4f809c5e126d013072", // dev
Name = "Разработчик",
},
});
});
modelBuilder.Entity<Well>(entity =>
{
entity.HasOne(d => d.Cluster)
.WithMany(p => p.Wells)
.HasForeignKey(d => d.IdCluster)
.HasConstraintName("t_well_t_cluster_id_fk");
// Todo: Setup relation table names (https://stackoverflow.com/questions/11769864/many-to-many-relationships-in-ef5-code-first-how-can-i-specify-table-name)
entity.HasMany(d => d.Companies)
.WithMany(p => p.Wells);
entity.HasOne(d => d.Telemetry)
.WithOne(p => p.Well)
.HasForeignKey<Well>(d => d.IdTelemetry)
.HasConstraintName("t_well_t_telemetry_id_fk");
});
FillData(modelBuilder);
}
private static void FillData(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Deposit>(entity =>
{
entity.HasData(new List<Deposit> {
new Deposit{Id = 1, Caption = "м/р 1", Latitude = 60.8705722222222, Longitude = 70.3811888888889 },
});
});
modelBuilder.Entity<Cluster>(entity =>
{
entity.HasData(new List<Cluster> {
new Cluster{Id = 1, Caption = "к221", IdDeposit = 1, Latitude = 60.8705722222222, Longitude = 70.3811888888889},
new Cluster{Id = 2, Caption = "к151", IdDeposit = 1, Latitude = 60.8205750000000, Longitude = 70.1343833333334},
new Cluster{Id = 3, Caption = "к611", IdDeposit = 1, Latitude = 60.8100666666667, Longitude = 69.7778388888889},
new Cluster{Id = 4, Caption = "к203", IdDeposit = 1, Latitude = 60.8928805555556, Longitude = 70.3272055555556},
new Cluster{Id = 5, Caption = "к39.1", IdDeposit = 1, Latitude = 60.6672055555556, Longitude = 69.6603861111111},
});
});
modelBuilder.Entity<Well>(entity =>
{
entity.HasData(new List<Well> {
new Well{Id = 1, IdCluster = 1, Caption = "скв 42669", Latitude = 60.8705722222222, Longitude = 70.3811888888889},
new Well{Id = 2, IdCluster = 1, Caption = "скв 16311", Latitude = 60.8705722222222, Longitude = 70.3811888888889},
new Well{Id = 3, IdCluster = 2, Caption = "скв 16315", Latitude = 60.8205750000000, Longitude = 70.1343833333334},
new Well{Id = 4, IdCluster = 2, Caption = "скв 16318", Latitude = 60.8205750000000, Longitude = 70.1343833333334},
new Well{Id = 5, IdCluster = 3, Caption = "скв 16310", Latitude = 60.8100666666667, Longitude = 69.7778388888889},
new Well{Id = 6, IdCluster = 4, Caption = "скв 16316", Latitude = 60.8928805555556, Longitude = 70.3272055555556},
new Well{Id = 7, IdCluster = 5, Caption = "скв 16312", Latitude = 60.6672055555556, Longitude = 69.6603861111111},
new Well{Id = 8, IdCluster = 5, Caption = "скв 16313", Latitude = 60.6672055555556, Longitude = 69.6603861111111},
new Well{Id = 9, IdCluster = 5, Caption = "скв 16314", Latitude = 60.6672055555556, Longitude = 69.6603861111111},
});
});
modelBuilder.Entity<Operation>(entity =>
{
entity.HasData(new List<Operation> {
new Operation {Id = 1, Name = "Невозможно определить операцию"},
new Operation {Id = 2, Name = "Роторное бурение" },
new Operation {Id = 3, Name = "Слайдирование" },
new Operation {Id = 4, Name = "Подъем с проработкой" },
new Operation {Id = 5, Name = "Спуск с проработкой" },
new Operation {Id = 6, Name = "Подъем с промывкой" },
new Operation {Id = 7, Name = "Спуск с промывкой" },
new Operation {Id = 8, Name = "Спуск в скважину" },
new Operation {Id = 9, Name = "Спуск с вращением" },
new Operation {Id = 10, Name = "Подъем из скважины" },
new Operation {Id = 11, Name = "Подъем с вращением" },
new Operation {Id = 12, Name = "Промывка в покое" },
new Operation {Id = 13, Name = "Промывка с вращением" },
new Operation {Id = 14, Name = "Удержание в клиньях" },
new Operation {Id = 15, Name = "Неподвижное состояние" },
new Operation {Id = 16, Name = "Вращение без циркуляции" },
new Operation {Id = 17, Name = "На поверхности" }
});
});
}
public IQueryable<Well> GetWellsForCompany(int idCompany)
{
return from well in Wells
.Include(w => w.Companies)
.Include(w => w.Cluster)
.ThenInclude(c => c.Deposit)
where well.Companies.Any(c => c.Id == idCompany)
select well;
}
public IQueryable<User> GetUsersByLogin(string login)
=> Users
.Include(e => e.Role)
.Include(e => e.Company)
.Where(e => e.Login == login);
public (DateTime From, DateTime To) GetDatesRange<TEntity>(int idTelemetry)
where TEntity : class, IIdTelemetryDate
{
var dbSet = Set<TEntity>();
var datesRange = (from m in dbSet
where m.IdTelemetry == idTelemetry
group m by m.IdTelemetry into g
select new
{
From = g.Min(d => d.Date),
To = g.Max(d => d.Date)
}).FirstOrDefault();
if (datesRange is null)
return (DateTime.MinValue, DateTime.MaxValue);
return (datesRange.From, datesRange.To);
}
public IEnumerable<(double? MinDepth, double? MaxDepth, DateTime BeginPeriodDate)> GetDepthToInterval(int telemetryId,
int intervalHoursTimestamp, int workStartTimestamp, double timezoneOffset)
{
//TODO: Сменить на LINQ группирование
using var command = Database.GetDbConnection().CreateCommand();
command.CommandText = $@"SELECT Min(t.bit_depth) AS MinDepth, Max(t.bit_depth) AS MaxDepth, Min(t.Date) AS dateStart
FROM t_data_saub_base AS t
WHERE id_telemetry = {telemetryId} AND t.Id % 10 = 0
GROUP BY floor((extract(epoch from t.date) - {workStartTimestamp} + {timezoneOffset}) / {intervalHoursTimestamp});";
Database.OpenConnection();
using var reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
yield return
(
(double?)reader.GetValue(0),
(double?)reader.GetValue(1),
(DateTime)reader.GetValue(2)
);
}
}
}
public async Task<int> CreatePartitionAsync<TEntity>(string propertyName, int id, CancellationToken token = default)
where TEntity : class
{
var dbSet = Set<TEntity>();
var baseTableName = dbSet.EntityType.GetTableName();
var schema = dbSet.EntityType.GetSchema();
var tableObject = Microsoft.EntityFrameworkCore.Metadata.StoreObjectIdentifier.Table(baseTableName, schema);
var tableName = baseTableName.Replace("_base", "");
var property = dbSet.EntityType.GetProperty(propertyName).GetColumnName(tableObject);
var query = $"CREATE TABLE {tableName}_{id} (like {baseTableName} including all, constraint partitioning_check check ({property} = 1)) INHERITS ({baseTableName});";
return await Database.ExecuteSqlRawAsync(query, token).ConfigureAwait(false);
}
}
}