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 Clusters { get; set; } public virtual DbSet Customers { get; set; } public virtual DbSet DataSaubBases { get; set; } public virtual DbSet Deposits { get; set; } public virtual DbSet Events { get; set; } public virtual DbSet Messages { get; set; } public virtual DbSet Telemetries { get; set; } public virtual DbSet TelemetryUsers { get; set; } public virtual DbSet Users { get; set; } public virtual DbSet UserRoles { get; set; } public virtual DbSet Wells { get; set; } public virtual DbSet Reports { get; set; } public virtual DbSet Operations { get; set; } public virtual DbSet TelemetryAnalysis { 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 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(entity => { entity.HasOne(d => d.Deposit) .WithMany(p => p.Clusters) .HasForeignKey(d => d.IdDeposit) .HasConstraintName("t_cluster_t_deposit_id_fk"); }); modelBuilder.Entity(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(entity => { entity.HasOne(d => d.Telemetry) .WithMany(p => p.Messages) .HasForeignKey(d => d.IdTelemetry) .HasConstraintName("t_messages_t_telemetry_id_fk"); }); modelBuilder.Entity(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(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(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(entity => { entity.HasData(new List{ new UserRole{ Id = 1, Caption = "Администратор", }, }); }); modelBuilder.Entity(entity => { entity.HasData(new List{ new Customer{ Id = 1, Caption = "\"ООО\" АСБ", }, }); }); modelBuilder.Entity(entity => { entity.HasOne(d => d.Customer) .WithMany(p => p.Users) .HasForeignKey(d => d.IdCustomer) .HasConstraintName("t_user_t_customer_id_fk"); entity.HasIndex(d => d.Login) .IsUnique(); entity.HasData(new List{ new User{ Id = 1, IdCustomer = 1, IdRole = 1, Level = int.MaxValue, Login = "dev", PasswordHash = "Vlcj|4fa529103dde7ff72cfe76185f344d4aa87931f8e1b2044e8a7739947c3d18923464eaad93843e4f809c5e126d013072", // dev Name = "Разработчик", }, }); }); modelBuilder.Entity(entity => { entity.HasOne(d => d.Cluster) .WithMany(p => p.Wells) .HasForeignKey(d => d.IdCluster) .HasConstraintName("t_well_t_cluster_id_fk"); entity.HasOne(d => d.Customer) .WithMany(p => p.Wells) .HasForeignKey(d => d.IdCustomer) .HasConstraintName("t_well_t_customer_id_fk"); entity.HasOne(d => d.Telemetry) .WithOne(p => p.Well) .HasForeignKey(d => d.IdTelemetry) .HasConstraintName("t_well_t_telemetry_id_fk"); }); FillData(modelBuilder); } private static void FillData(ModelBuilder modelBuilder) { modelBuilder.Entity(entity => { entity.HasData(new List { new Deposit{Id = 1, Caption = "м/р 1", Latitude = 60.8705722222222, Longitude = 70.3811888888889 }, }); }); modelBuilder.Entity(entity => { entity.HasData(new List { 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(entity => { entity.HasData(new List { new Well{Id = 1, IdCluster = 1, IdCustomer = 1, Caption = "скв 42669", Latitude = 60.8705722222222, Longitude = 70.3811888888889}, new Well{Id = 2, IdCluster = 1, IdCustomer = 1, Caption = "скв 16311", Latitude = 60.8705722222222, Longitude = 70.3811888888889}, new Well{Id = 3, IdCluster = 2, IdCustomer = 1, Caption = "скв 16315", Latitude = 60.8205750000000, Longitude = 70.1343833333334}, new Well{Id = 4, IdCluster = 2, IdCustomer = 1, Caption = "скв 16318", Latitude = 60.8205750000000, Longitude = 70.1343833333334}, new Well{Id = 5, IdCluster = 3, IdCustomer = 1, Caption = "скв 16310", Latitude = 60.8100666666667, Longitude = 69.7778388888889}, new Well{Id = 6, IdCluster = 4, IdCustomer = 1, Caption = "скв 16316", Latitude = 60.8928805555556, Longitude = 70.3272055555556}, new Well{Id = 7, IdCluster = 5, IdCustomer = 1, Caption = "скв 16312", Latitude = 60.6672055555556, Longitude = 69.6603861111111}, new Well{Id = 8, IdCluster = 5, IdCustomer = 1, Caption = "скв 16313", Latitude = 60.6672055555556, Longitude = 69.6603861111111}, new Well{Id = 9, IdCluster = 5, IdCustomer = 1, Caption = "скв 16314", Latitude = 60.6672055555556, Longitude = 69.6603861111111}, }); }); modelBuilder.Entity(entity => { entity.HasData(new List { 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 GetWellsByCustomer(int idCustomer) { return from well in Wells .Include(w => w.Customer) .Include(w => w.Cluster) .ThenInclude(c => c.Deposit) where well.IdCustomer == idCustomer select well; } public IQueryable GetUsersByLogin(string login) => Users .Include(e => e.Role) .Include(e => e.Customer) .Where(e => e.Login == login); public (DateTime From, DateTime To) GetDatesRange(int idTelemetry) where TEntity : class, IIdTelemetryDate { var dbSet = Set(); 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 CreatePartitionAsync(string propertyName, int id, CancellationToken token = default) where TEntity : class { var dbSet = Set(); 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); } } }