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();
}
}
}