using MongoDB.Bson; using MongoDB.Driver; using Npgsql; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace RouteGuideMongoDBImplement { /// /// Класс для переноса данных между БД /// public class DataTransfer { /// /// Параметры подключения к базе данных PostgreSQL /// private readonly string _pgsqlDBConnectionString = "Host=192.168.0.108;Port=5432;Database=RouteGuide;Username=postgres;Password=2004"; /// /// Параметры подключения к базе данных MongoDB /// private readonly string _mongoDBConnectionString = "mongodb://localhost:27017"; /// /// Название базы данных /// private readonly string _databaseName = "RouteGuideDatabase"; /// /// Клиент MongoDB /// public readonly MongoClient _client; /// /// База данных MongoDB /// private readonly IMongoDatabase _database; /// /// Коллекция "Водители" /// private IMongoCollection Drivers => _database.GetCollection("Drivers"); /// /// Коллекция "Транспорт" /// private IMongoCollection Transport => _database.GetCollection("Transport"); /// /// Коллекция "Маршруты" /// private IMongoCollection Routes => _database.GetCollection("Routes"); /// /// Коллекция "Остановки" /// private IMongoCollection Stops => _database.GetCollection("Stops"); /// /// Связь для сущностей "Маршруты" и "Остановки" /// private IMongoCollection RouteStops => _database.GetCollection("RouteStops"); /// /// Коллекция "Расписания" /// private IMongoCollection Schedules => _database.GetCollection("Schedules"); /// /// Конструктор /// public DataTransfer() { _client = new MongoClient(_mongoDBConnectionString); _database = _client.GetDatabase(_databaseName); } /// /// Начать перенос данных /// public void SyncData() { // Переносим данные Transfer("Drivers"); Transfer("Transport"); Transfer("Routes"); Transfer("Stops"); Transfer("RouteStops"); Transfer("Schedules"); // Настраиваем корректные связи var transportCollection = Transport.Find(Builders.Filter.Empty).ToList(); var routesCollection = Routes.Find(Builders.Filter.Empty).ToList(); var schedulesCollection = Schedules.Find(Builders.Filter.Empty).ToList(); // Связь между сущностями "Транспорт" и "Водитель" transportCollection.ForEach(t => { int tempDriverId = t.GetValue("DriverId").ToInt32(); var driverId = Drivers .Find(Builders.Filter.Eq("Id", tempDriverId)) .FirstOrDefaultAsync() .Result.GetValue("_id") .ToString(); var driver = Drivers .Find(Builders.Filter.Eq("Id", tempDriverId)) .Project(Builders.Projection.Exclude("Id")) .FirstOrDefault(); var filter = Builders.Filter.Eq("_id", t.GetValue("_id")); var updateDriverId = Builders.Update.Set("DriverId", driverId); var updateDriver = Builders.Update.Set("Driver", driver); Transport.UpdateOneAsync(filter, updateDriverId); Transport.UpdateOneAsync(filter, updateDriver); }); // Связь между сущностями "Маршрут" и "Транспорт" routesCollection.ForEach(r => { int tempTransportId = r.GetValue("TransportId").ToInt32(); var transportId = Transport .Find(Builders.Filter.Eq("Id", tempTransportId)) .FirstOrDefaultAsync() .Result.GetValue("_id") .ToString(); var transport = Transport .Find(Builders.Filter.Eq("Id", tempTransportId)) .Project(Builders.Projection.Exclude("Id")) .FirstOrDefault(); var filter = Builders.Filter.Eq("_id", r.GetValue("_id")); var updateTransportId = Builders.Update.Set("TransportId", transportId); var updateTransport = Builders.Update.Set("Transport", transport); Routes.UpdateOneAsync(filter, updateTransportId); Routes.UpdateOneAsync(filter, updateTransport); }); // Связь между сущностями "Маршруты" и "Остановки" routesCollection.ForEach(r => { var tempRouteId = r.GetValue("Id").ToInt32(); var routeStops = RouteStops .Find(Builders.Filter.Eq("RouteId", tempRouteId)) .ToList(); var updateStops = new Dictionary(); routeStops.ForEach(rs => { var tempStopId = rs.GetValue("StopId").ToInt32(); var stop = Stops .Find(Builders.Filter.Eq("Id", tempStopId)) .Project(Builders.Projection.Exclude("Id")) .FirstOrDefault(); if (stop != null) { var stopId = stop.GetValue("_id").ToString(); var stopNumber = rs.GetValue("Number").ToInt32(); updateStops.Add(stopId!, (stop, stopNumber)); } }); var filter = Builders.Filter.Eq("_id", r.GetValue("_id")); var update = Builders.Update.Set("Stops", updateStops); Routes.UpdateOneAsync(filter, update); }); // Связь между сущностями "Расписание" и "Маршрут" schedulesCollection.ForEach(s => { int tempRouteId = s.GetValue("RouteId").ToInt32(); var routeId = Routes .Find(Builders.Filter.Eq("Id", tempRouteId)) .FirstOrDefaultAsync() .Result.GetValue("_id") .ToString(); var route = Routes .Find(Builders.Filter.Eq("Id", tempRouteId)) .Project(Builders.Projection.Exclude("Id")) .FirstOrDefault(); var filter = Builders.Filter.Eq("_id", s.GetValue("_id")); var updateRouteId = Builders.Update.Set("RouteId", routeId); var updateRoute = Builders.Update.Set("Route", route); Schedules.UpdateOneAsync(filter, updateRouteId); Schedules.UpdateOneAsync(filter, updateRoute); }); // Убираем поле "Id" var update = Builders.Update.Unset("Id"); Drivers.UpdateMany(new BsonDocument(), update); Transport.UpdateMany(new BsonDocument(), update); Routes.UpdateMany(new BsonDocument(), update); Stops.UpdateMany(new BsonDocument(), update); Schedules.UpdateMany(new BsonDocument(), update); // Удаление коллекции для связи сущностей "Маршруты" и "Остановки" RouteStops.Database.DropCollection("RouteStops"); } /// /// Перенос данных из таблицы в коллекцию /// /// private void Transfer(string collectionName) { using var connection = new NpgsqlConnection(_pgsqlDBConnectionString); connection.Open(); using var command = new NpgsqlCommand($"SELECT * FROM \"{collectionName}\"", connection); using var reader = command.ExecuteReader(); var collection = _database.GetCollection(collectionName); while (reader.Read()) { var document = new BsonDocument(); for (int i = 0; i < reader.FieldCount; i++) { string fieldName = reader.GetName(i); object value = reader.GetValue(i); document.Add(fieldName, BsonValue.Create(value)); } collection.InsertOne(document); } reader.Close(); command.Cancel(); connection.Close(); } } }