MongoDBImplement / Add Data transfer

This commit is contained in:
parent 63995f51c2
commit ab513e4064
8 changed files with 716 additions and 465 deletions

View File

@ -0,0 +1,234 @@
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
{
/// <summary>
/// Класс для переноса данных между БД
/// </summary>
public class DataTransfer
{
/// <summary>
/// Параметры подключения к базе данных PostgreSQL
/// </summary>
private readonly string _pgsqlDBConnectionString = "Host=192.168.0.108;Port=5432;Database=RouteGuide;Username=postgres;Password=2004";
/// <summary>
/// Параметры подключения к базе данных MongoDB
/// </summary>
private readonly string _mongoDBConnectionString = "mongodb://localhost:27017";
/// <summary>
/// Название базы данных
/// </summary>
private readonly string _databaseName = "RouteGuideDatabase";
/// <summary>
/// Клиент MongoDB
/// </summary>
public readonly MongoClient _client;
/// <summary>
/// База данных MongoDB
/// </summary>
private readonly IMongoDatabase _database;
/// <summary>
/// Коллекция "Водители"
/// </summary>
private IMongoCollection<BsonDocument> Drivers => _database.GetCollection<BsonDocument>("Drivers");
/// <summary>
/// Коллекция "Транспорт"
/// </summary>
private IMongoCollection<BsonDocument> Transport => _database.GetCollection<BsonDocument>("Transport");
/// <summary>
/// Коллекция "Маршруты"
/// </summary>
private IMongoCollection<BsonDocument> Routes => _database.GetCollection<BsonDocument>("Routes");
/// <summary>
/// Коллекция "Остановки"
/// </summary>
private IMongoCollection<BsonDocument> Stops => _database.GetCollection<BsonDocument>("Stops");
/// <summary>
/// Связь для сущностей "Маршруты" и "Остановки"
/// </summary>
private IMongoCollection<BsonDocument> RouteStops => _database.GetCollection<BsonDocument>("RouteStops");
/// <summary>
/// Коллекция "Расписания"
/// </summary>
private IMongoCollection<BsonDocument> Schedules => _database.GetCollection<BsonDocument>("Schedules");
/// <summary>
/// Конструктор
/// </summary>
public DataTransfer()
{
_client = new MongoClient(_mongoDBConnectionString);
_database = _client.GetDatabase(_databaseName);
}
/// <summary>
/// Начать перенос данных
/// </summary>
public void SyncData()
{
// Переносим данные
Transfer("Drivers");
Transfer("Transport");
Transfer("Routes");
Transfer("Stops");
Transfer("RouteStops");
Transfer("Schedules");
// Настраиваем корректные связи
var transportCollection = Transport.Find(Builders<BsonDocument>.Filter.Empty).ToList();
var routesCollection = Routes.Find(Builders<BsonDocument>.Filter.Empty).ToList();
var schedulesCollection = Schedules.Find(Builders<BsonDocument>.Filter.Empty).ToList();
// Связь между сущностями "Транспорт" и "Водитель"
transportCollection.ForEach(t =>
{
int tempDriverId = t.GetValue("DriverId").ToInt32();
var driverId = Drivers
.Find(Builders<BsonDocument>.Filter.Eq("Id", tempDriverId))
.FirstOrDefaultAsync()
.Result.GetValue("_id")
.ToString();
var driver = Drivers
.Find(Builders<BsonDocument>.Filter.Eq("Id", tempDriverId))
.Project(Builders<BsonDocument>.Projection.Exclude("Id"))
.FirstOrDefault();
var filter = Builders<BsonDocument>.Filter.Eq("_id", t.GetValue("_id"));
var updateDriverId = Builders<BsonDocument>.Update.Set("DriverId", driverId);
var updateDriver = Builders<BsonDocument>.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<BsonDocument>.Filter.Eq("Id", tempTransportId))
.FirstOrDefaultAsync()
.Result.GetValue("_id")
.ToString();
var transport = Transport
.Find(Builders<BsonDocument>.Filter.Eq("Id", tempTransportId))
.Project(Builders<BsonDocument>.Projection.Exclude("Id"))
.FirstOrDefault();
var filter = Builders<BsonDocument>.Filter.Eq("_id", r.GetValue("_id"));
var updateTransportId = Builders<BsonDocument>.Update.Set("TransportId", transportId);
var updateTransport = Builders<BsonDocument>.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<BsonDocument>.Filter.Eq("RouteId", tempRouteId))
.ToList();
var updateStops = new Dictionary<string, (BsonDocument, int)>();
routeStops.ForEach(rs =>
{
var tempStopId = rs.GetValue("StopId").ToInt32();
var stop = Stops
.Find(Builders<BsonDocument>.Filter.Eq("Id", tempStopId))
.Project(Builders<BsonDocument>.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<BsonDocument>.Filter.Eq("_id", r.GetValue("_id"));
var update = Builders<BsonDocument>.Update.Set("Stops", updateStops);
Routes.UpdateOneAsync(filter, update);
});
// Связь между сущностями "Расписание" и "Маршрут"
schedulesCollection.ForEach(s =>
{
int tempRouteId = s.GetValue("RouteId").ToInt32();
var routeId = Routes
.Find(Builders<BsonDocument>.Filter.Eq("Id", tempRouteId))
.FirstOrDefaultAsync()
.Result.GetValue("_id")
.ToString();
var route = Routes
.Find(Builders<BsonDocument>.Filter.Eq("Id", tempRouteId))
.Project(Builders<BsonDocument>.Projection.Exclude("Id"))
.FirstOrDefault();
var filter = Builders<BsonDocument>.Filter.Eq("_id", s.GetValue("_id"));
var updateRouteId = Builders<BsonDocument>.Update.Set("RouteId", routeId);
var updateRoute = Builders<BsonDocument>.Update.Set("Route", route);
Schedules.UpdateOneAsync(filter, updateRouteId);
Schedules.UpdateOneAsync(filter, updateRoute);
});
// Убираем поле "Id"
var update = Builders<BsonDocument>.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");
}
/// <summary>
/// Перенос данных из таблицы в коллекцию
/// </summary>
/// <param name="collectionName"></param>
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<BsonDocument>(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();
}
}
}

View File

@ -141,11 +141,9 @@ namespace RouteGuideMongoDBImplement.Implements
public RouteViewModel? Update(RouteBindingModel model) public RouteViewModel? Update(RouteBindingModel model)
{ {
using var context = new RouteGuideDatabase(); using var context = new RouteGuideDatabase();
using var session = context._client.StartSession();
try
{
var filterBuilder = Builders<Route>.Filter; var filterBuilder = Builders<Route>.Filter;
var filter = filterBuilder.Eq(x => x.Id, model.Id); var filter = filterBuilder.Eq(x => x.Id, model.Id.ToString());
var route = context.Routes.Find(filter).FirstOrDefault(); var route = context.Routes.Find(filter).FirstOrDefault();
if (route == null) if (route == null)
@ -156,15 +154,8 @@ namespace RouteGuideMongoDBImplement.Implements
route.Update(model); route.Update(model);
route.UpdateStops(context, model); route.UpdateStops(context, model);
context.Routes.ReplaceOne(filter, route); context.Routes.ReplaceOne(filter, route);
session.CommitTransaction();
return route.GetViewModel; return route.GetViewModel;
} }
catch
{
session.AbortTransaction();
throw;
}
}
/// <summary> /// <summary>
/// Удаление элемента /// Удаление элемента

View File

@ -35,7 +35,7 @@ namespace RouteGuideMongoDBImplement.Models
/// Идентификатор транспорта /// Идентификатор транспорта
/// </summary> /// </summary>
[BsonRequired] [BsonRequired]
[BsonElement("transport_id")] [BsonElement("TransportId")]
public string? TransportId { get; private set; } public string? TransportId { get; private set; }
/// <summary> /// <summary>

View File

@ -53,7 +53,7 @@ namespace RouteGuideMongoDBImplement.Models
/// Идентификатор маршрута /// Идентификатор маршрута
/// </summary> /// </summary>
[BsonRequired] [BsonRequired]
[BsonElement("route_id")] [BsonElement("RouteId")]
public string? RouteId { get; private set; } public string? RouteId { get; private set; }
/// <summary> /// <summary>

View File

@ -48,7 +48,7 @@ namespace RouteGuideMongoDBImplement.Models
/// Идентификатор водителя /// Идентификатор водителя
/// </summary> /// </summary>
[BsonRequired] [BsonRequired]
[BsonElement("driver_id")] [BsonElement("DriverId")]
public string? DriverId { get; private set; } public string? DriverId { get; private set; }
/// <summary> /// <summary>

View File

@ -14,6 +14,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="MongoDB.Bson" Version="2.25.0" /> <PackageReference Include="MongoDB.Bson" Version="2.25.0" />
<PackageReference Include="MongoDB.Driver" Version="2.25.0" /> <PackageReference Include="MongoDB.Driver" Version="2.25.0" />
<PackageReference Include="Npgsql" Version="7.0.4" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -45,6 +45,7 @@
buttonDelete = new Button(); buttonDelete = new Button();
buttonRefresh = new Button(); buttonRefresh = new Button();
dataGridView = new DataGridView(); dataGridView = new DataGridView();
buttonSyncData = new Button();
menuStrip1.SuspendLayout(); menuStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout(); SuspendLayout();
@ -103,35 +104,35 @@
// DriversTestsToolStripMenuItem // DriversTestsToolStripMenuItem
// //
DriversTestsToolStripMenuItem.Name = "DriversTestsToolStripMenuItem"; DriversTestsToolStripMenuItem.Name = "DriversTestsToolStripMenuItem";
DriversTestsToolStripMenuItem.Size = new Size(180, 22); DriversTestsToolStripMenuItem.Size = new Size(139, 22);
DriversTestsToolStripMenuItem.Text = "Водители"; DriversTestsToolStripMenuItem.Text = "Водители";
DriversTestsToolStripMenuItem.Click += DriversTestsToolStripMenuItem_Click; DriversTestsToolStripMenuItem.Click += DriversTestsToolStripMenuItem_Click;
// //
// TransportTestsToolStripMenuItem // TransportTestsToolStripMenuItem
// //
TransportTestsToolStripMenuItem.Name = "TransportTestsToolStripMenuItem"; TransportTestsToolStripMenuItem.Name = "TransportTestsToolStripMenuItem";
TransportTestsToolStripMenuItem.Size = new Size(180, 22); TransportTestsToolStripMenuItem.Size = new Size(139, 22);
TransportTestsToolStripMenuItem.Text = "Транспорт"; TransportTestsToolStripMenuItem.Text = "Транспорт";
TransportTestsToolStripMenuItem.Click += TransportTestsToolStripMenuItem_Click; TransportTestsToolStripMenuItem.Click += TransportTestsToolStripMenuItem_Click;
// //
// RoutesTestsToolStripMenuItem // RoutesTestsToolStripMenuItem
// //
RoutesTestsToolStripMenuItem.Name = "RoutesTestsToolStripMenuItem"; RoutesTestsToolStripMenuItem.Name = "RoutesTestsToolStripMenuItem";
RoutesTestsToolStripMenuItem.Size = new Size(180, 22); RoutesTestsToolStripMenuItem.Size = new Size(139, 22);
RoutesTestsToolStripMenuItem.Text = "Маршруты"; RoutesTestsToolStripMenuItem.Text = "Маршруты";
RoutesTestsToolStripMenuItem.Click += RoutesTestsToolStripMenuItem_Click; RoutesTestsToolStripMenuItem.Click += RoutesTestsToolStripMenuItem_Click;
// //
// StopsTestsToolStripMenuItem // StopsTestsToolStripMenuItem
// //
StopsTestsToolStripMenuItem.Name = "StopsTestsToolStripMenuItem"; StopsTestsToolStripMenuItem.Name = "StopsTestsToolStripMenuItem";
StopsTestsToolStripMenuItem.Size = new Size(180, 22); StopsTestsToolStripMenuItem.Size = new Size(139, 22);
StopsTestsToolStripMenuItem.Text = "Остановки"; StopsTestsToolStripMenuItem.Text = "Остановки";
StopsTestsToolStripMenuItem.Click += StopsTestsToolStripMenuItem_Click; StopsTestsToolStripMenuItem.Click += StopsTestsToolStripMenuItem_Click;
// //
// SchedulesTestsToolStripMenuItem // SchedulesTestsToolStripMenuItem
// //
SchedulesTestsToolStripMenuItem.Name = "SchedulesTestsToolStripMenuItem"; SchedulesTestsToolStripMenuItem.Name = "SchedulesTestsToolStripMenuItem";
SchedulesTestsToolStripMenuItem.Size = new Size(180, 22); SchedulesTestsToolStripMenuItem.Size = new Size(139, 22);
SchedulesTestsToolStripMenuItem.Text = "Расписания"; SchedulesTestsToolStripMenuItem.Text = "Расписания";
SchedulesTestsToolStripMenuItem.Click += SchedulesTestsToolStripMenuItem_Click; SchedulesTestsToolStripMenuItem.Click += SchedulesTestsToolStripMenuItem_Click;
// //
@ -192,11 +193,22 @@
dataGridView.Size = new Size(850, 337); dataGridView.Size = new Size(850, 337);
dataGridView.TabIndex = 5; dataGridView.TabIndex = 5;
// //
// buttonSyncData
//
buttonSyncData.Location = new Point(885, 309);
buttonSyncData.Name = "buttonSyncData";
buttonSyncData.Size = new Size(75, 40);
buttonSyncData.TabIndex = 6;
buttonSyncData.Text = "Синхр. данные";
buttonSyncData.UseVisualStyleBackColor = true;
buttonSyncData.Click += buttonSyncData_Click;
//
// FormMain // FormMain
// //
AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(984, 361); ClientSize = new Size(984, 361);
Controls.Add(buttonSyncData);
Controls.Add(dataGridView); Controls.Add(dataGridView);
Controls.Add(buttonRefresh); Controls.Add(buttonRefresh);
Controls.Add(buttonDelete); Controls.Add(buttonDelete);
@ -233,5 +245,6 @@
private ToolStripMenuItem RoutesTestsToolStripMenuItem; private ToolStripMenuItem RoutesTestsToolStripMenuItem;
private ToolStripMenuItem StopsTestsToolStripMenuItem; private ToolStripMenuItem StopsTestsToolStripMenuItem;
private ToolStripMenuItem SchedulesTestsToolStripMenuItem; private ToolStripMenuItem SchedulesTestsToolStripMenuItem;
private Button buttonSyncData;
} }
} }

View File

@ -2,6 +2,7 @@ using Microsoft.Extensions.Logging;
using RouteGuideBusinessLogics.BusinessLogics; using RouteGuideBusinessLogics.BusinessLogics;
using RouteGuideContracts.BindingModels; using RouteGuideContracts.BindingModels;
using RouteGuideContracts.BusinessLogicsContracts; using RouteGuideContracts.BusinessLogicsContracts;
using RouteGuideMongoDBImplement;
namespace RouteGuideView namespace RouteGuideView
{ {
@ -247,6 +248,17 @@ namespace RouteGuideView
LoadData(); LoadData();
} }
/// <summary>
/// Êíîïêà "Ñèíõðîíèçèðîâàòü äàííûå"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonSyncData_Click(object sender, EventArgs e)
{
DataTransfer dataTransfer = new DataTransfer();
dataTransfer.SyncData();
}
/// <summary> /// <summary>
/// Çàãðóçêà äàííûõ /// Çàãðóçêà äàííûõ
/// </summary> /// </summary>