diff --git a/RouteGuide/RouteGuide.sln b/RouteGuide/RouteGuide.sln index 15cadd5..188134b 100644 --- a/RouteGuide/RouteGuide.sln +++ b/RouteGuide/RouteGuide.sln @@ -9,6 +9,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideDataModels", "Rou EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideContracts", "RouteGuideContracts\RouteGuideContracts.csproj", "{A27C89B3-F629-4553-B928-EE22147EBD86}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideBusinessLogic", "RouteGuideBusinessLogic\RouteGuideBusinessLogic.csproj", "{669B7493-597E-4A60-B42C-95F91845C45A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideDatabaseImplements", "RouteGuideDatabaseImplement\RouteGuideDatabaseImplements.csproj", "{DF4E9628-8414-4D81-8350-EC93961ECC3C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -27,6 +31,14 @@ Global {A27C89B3-F629-4553-B928-EE22147EBD86}.Debug|Any CPU.Build.0 = Debug|Any CPU {A27C89B3-F629-4553-B928-EE22147EBD86}.Release|Any CPU.ActiveCfg = Release|Any CPU {A27C89B3-F629-4553-B928-EE22147EBD86}.Release|Any CPU.Build.0 = Release|Any CPU + {669B7493-597E-4A60-B42C-95F91845C45A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {669B7493-597E-4A60-B42C-95F91845C45A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {669B7493-597E-4A60-B42C-95F91845C45A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {669B7493-597E-4A60-B42C-95F91845C45A}.Release|Any CPU.Build.0 = Release|Any CPU + {DF4E9628-8414-4D81-8350-EC93961ECC3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DF4E9628-8414-4D81-8350-EC93961ECC3C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DF4E9628-8414-4D81-8350-EC93961ECC3C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DF4E9628-8414-4D81-8350-EC93961ECC3C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/RouteGuide/RouteGuideBusinessLogic/BusinessLogic/RouteLogic.cs b/RouteGuide/RouteGuideBusinessLogic/BusinessLogic/RouteLogic.cs new file mode 100644 index 0000000..7241558 --- /dev/null +++ b/RouteGuide/RouteGuideBusinessLogic/BusinessLogic/RouteLogic.cs @@ -0,0 +1,114 @@ +using Microsoft.Extensions.Logging; +using RouteGuideContracts.BindingModels; +using RouteGuideContracts.BusinessLogicContracts; +using RouteGuideContracts.SearchModels; +using RouteGuideContracts.StoragesModels; +using RouteGuideContracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RouteGuideBusinessLogic.BusinessLogic +{ + public class RouteLogic : IRouteLogic + { + private readonly ILogger _logger; + private readonly IRouteStorage _routeStorage; + + public RouteLogic(ILogger logger, IRouteStorage routeStorage) + { + _logger = logger; + _routeStorage = routeStorage; + } + + public bool Create(RouteBindingModel model) + { + CheckModel(model); + if (_routeStorage.Insert(model) == null) + { + _logger.LogWarning("Insert operation failed"); + return false; + } + return true; + } + + public bool Delete(RouteBindingModel model) + { + CheckModel(model, false); + _logger.LogInformation("Delete. Id:{Id}", model.Id); + if (_routeStorage.Delete(model) == null) + { + _logger.LogWarning("Delete operation failed"); + return false; + } + return true; + } + + public RouteViewModel? ReadElement(RouteSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. RouteName:{RouteName}.Id:{ Id}", model.Name, model.Id); + var element = _routeStorage.GetElement(model); + if (element == null) + { + _logger.LogWarning("ReadElement element not found"); + return null; + } + _logger.LogInformation("ReadElement find. Id:{Id}", element.Id); + return element; + } + + public List? ReadList(RouteSearchModel? model) + { + _logger.LogInformation("ReadList. RouteName:{RoutetName}.Id:{ Id}", model?.Name, model?.Id); + var list = model == null ? _routeStorage.GetFullList() : _routeStorage.GetFilteredList(model); + if (list == null) + { + _logger.LogWarning("ReadList return null list"); + return null; + } + _logger.LogInformation("ReadList. Count:{Count}", list.Count); + return list; + } + + public bool Update(RouteBindingModel model) + { + CheckModel(model); + if (_routeStorage.Update(model) == null) + { + _logger.LogWarning("Update operation failed"); + return false; + } + return true; + } + private void CheckModel(RouteBindingModel model, bool withParams = true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) + { + return; + } + if (string.IsNullOrEmpty(model.Name)) + { + throw new ArgumentNullException("Нет названия", nameof(model.Name)); + } + _logger.LogInformation("Route. Name:{Name}. Id: { Id}", model.Name, model.Id); + var element = _routeStorage.GetElement(new RouteSearchModel + { + Name = model.Name + }); + if (element != null && element.Id != model.Id) + { + throw new InvalidOperationException("Route с таким названием уже есть"); + } + } + } +} diff --git a/RouteGuide/RouteGuideBusinessLogic/BusinessLogic/StopLogic.cs b/RouteGuide/RouteGuideBusinessLogic/BusinessLogic/StopLogic.cs new file mode 100644 index 0000000..bb77eb2 --- /dev/null +++ b/RouteGuide/RouteGuideBusinessLogic/BusinessLogic/StopLogic.cs @@ -0,0 +1,115 @@ +using Microsoft.Extensions.Logging; +using RouteGuideContracts.BindingModels; +using RouteGuideContracts.BusinessLogicContracts; +using RouteGuideContracts.SearchModels; +using RouteGuideContracts.StoragesModels; +using RouteGuideContracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RouteGuideBusinessLogic.BusinessLogic +{ + public class StopLogic : IStopLogic + { + private readonly ILogger _logger; + private readonly IStopStorage _stopStorage; + + public StopLogic(ILogger logger, IStopStorage stopStorage) + { + _logger = logger; + _stopStorage = stopStorage; + } + + public bool Create(StopBindingModel model) + { + CheckModel(model); + if (_stopStorage.Insert(model) == null) + { + _logger.LogWarning("Insert operation failed"); + return false; + } + return true; + } + + public bool Delete(StopBindingModel model) + { + CheckModel(model, false); + _logger.LogInformation("Delete. Id:{Id}", model.Id); + if (_stopStorage.Delete(model) == null) + { + _logger.LogWarning("Delete operation failed"); + return false; + } + return true; + } + + public StopViewModel? ReadElement(StopSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. Name:{Name}.Id:{ Id}", model.Name, model.Id); + var element = _stopStorage.GetElement(model); + if (element == null) + { + _logger.LogWarning("ReadElement element not found"); + return null; + } + _logger.LogInformation("ReadElement find. Id:{Id}", element.Id); + return element; + } + + public List? ReadList(StopSearchModel? model) + { + _logger.LogInformation("ReadList. Name:{Name}.Id:{ Id}", model?.Name, model?.Id); + var list = model == null ? _stopStorage.GetFullList() : _stopStorage.GetFilteredList(model); + if (list == null) + { + _logger.LogWarning("ReadList return null list"); + return null; + } + _logger.LogInformation("ReadList. Count:{Count}", list.Count); + return list; + } + + public bool Update(StopBindingModel model) + { + CheckModel(model); + if (_stopStorage.Update(model) == null) + { + _logger.LogWarning("Update operation failed"); + return false; + } + return true; + } + private void CheckModel(StopBindingModel model, bool withParams = true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) + { + return; + } + if (string.IsNullOrEmpty(model.Name)) + { + throw new ArgumentNullException("Нет названия", nameof(model.Name)); + } + + _logger.LogInformation("Stop. Name:{Name}. Id: { Id}", model.Name, model.Id); + var element = _stopStorage.GetElement(new StopSearchModel + { + Name = model.Name + }); + if (element != null && element.Id != model.Id) + { + throw new InvalidOperationException("Stop с таким названием уже есть"); + } + } + } +} diff --git a/RouteGuide/RouteGuideBusinessLogic/BusinessLogic/TransportLogic.cs b/RouteGuide/RouteGuideBusinessLogic/BusinessLogic/TransportLogic.cs new file mode 100644 index 0000000..239af02 --- /dev/null +++ b/RouteGuide/RouteGuideBusinessLogic/BusinessLogic/TransportLogic.cs @@ -0,0 +1,114 @@ +using Microsoft.Extensions.Logging; +using RouteGuideContracts.BindingModels; +using RouteGuideContracts.BusinessLogicContracts; +using RouteGuideContracts.SearchModels; +using RouteGuideContracts.StoragesModels; +using RouteGuideContracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RouteGuideBusinessLogic.BusinessLogic +{ + public class TransportLogic : ITransportLogic + { + private readonly ILogger _logger; + private readonly ITransportStorage _transportStorage; + + public TransportLogic(ILogger logger, ITransportStorage transportStorage) + { + _logger = logger; + _transportStorage = transportStorage; + } + + public bool Create(TransportBindingModel model) + { + CheckModel(model); + if (_transportStorage.Insert(model) == null) + { + _logger.LogWarning("Insert operation failed"); + return false; + } + return true; + } + + public bool Delete(TransportBindingModel model) + { + CheckModel(model, false); + _logger.LogInformation("Delete. Id:{Id}", model.Id); + if (_transportStorage.Delete(model) == null) + { + _logger.LogWarning("Delete operation failed"); + return false; + } + return true; + } + + public TransportViewModel? ReadElement(TransportSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. DriverName:{DriverName}.Id:{ Id}", model.DriverName, model.Id); + var element = _transportStorage.GetElement(model); + if (element == null) + { + _logger.LogWarning("ReadElement element not found"); + return null; + } + _logger.LogInformation("ReadElement find. Id:{Id}", element.Id); + return element; + } + + public List? ReadList(TransportSearchModel? model) + { + _logger.LogInformation("ReadList. DriverName:{DriverName}.Id:{ Id}", model?.DriverName, model?.Id); + var list = model == null ? _transportStorage.GetFullList() : _transportStorage.GetFilteredList(model); + if (list == null) + { + _logger.LogWarning("ReadList return null list"); + return null; + } + _logger.LogInformation("ReadList. Count:{Count}", list.Count); + return list; + } + + public bool Update(TransportBindingModel model) + { + CheckModel(model); + if (_transportStorage.Update(model) == null) + { + _logger.LogWarning("Update operation failed"); + return false; + } + return true; + } + private void CheckModel(TransportBindingModel model, bool withParams = true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) + { + return; + } + if (string.IsNullOrEmpty(model.DriverName)) + { + throw new ArgumentNullException("Нет водителя ", nameof(model.DriverName)); + } + _logger.LogInformation("Transport. DriverName:{DriverName}. TransportTypeId:{ TransportTypeId}. Id: { Id}", model.DriverName, model.TransportTypeId, model.Id); + var element = _transportStorage.GetElement(new TransportSearchModel + { + DriverName = model.DriverName + }); + if (element != null && element.Id != model.Id) + { + throw new InvalidOperationException("Transport с таким названием уже есть"); + } + } + } +} diff --git a/RouteGuide/RouteGuideBusinessLogic/BusinessLogic/TransportTypeLogic.cs b/RouteGuide/RouteGuideBusinessLogic/BusinessLogic/TransportTypeLogic.cs new file mode 100644 index 0000000..a8235c1 --- /dev/null +++ b/RouteGuide/RouteGuideBusinessLogic/BusinessLogic/TransportTypeLogic.cs @@ -0,0 +1,118 @@ +using Microsoft.Extensions.Logging; +using RouteGuideContracts.BindingModels; +using RouteGuideContracts.BusinessLogicContracts; +using RouteGuideContracts.SearchModels; +using RouteGuideContracts.StoragesModels; +using RouteGuideContracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RouteGuideBusinessLogic.BusinessLogic +{ + public class TransportTypeLogic : ITransportTypeLogic + { + private readonly ILogger _logger; + private readonly ITransportTypeStorage _transportTypeStorage; + + public TransportTypeLogic(ILogger logger, ITransportTypeStorage transportTypeStorage) + { + _logger = logger; + _transportTypeStorage = transportTypeStorage; + } + + public bool Create(TransportTypeBindingModel model) + { + CheckModel(model); + if (_transportTypeStorage.Insert(model) == null) + { + _logger.LogWarning("Insert operation failed"); + return false; + } + return true; + } + + public bool Delete(TransportTypeBindingModel model) + { + CheckModel(model, false); + _logger.LogInformation("Delete. Id:{Id}", model.Id); + if (_transportTypeStorage.Delete(model) == null) + { + _logger.LogWarning("Delete operation failed"); + return false; + } + return true; + } + + public TransportTypeViewModel? ReadElement(TransportTypeSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. Name:{Name}.Id:{ Id}", model.Name, model.Id); + var element = _transportTypeStorage.GetElement(model); + if (element == null) + { + _logger.LogWarning("ReadElement element not found"); + return null; + } + _logger.LogInformation("ReadElement find. Id:{Id}", element.Id); + return element; + } + + public List? ReadList(TransportTypeSearchModel? model) + { + _logger.LogInformation("ReadList. Name:{Name}.Id:{ Id}", model?.Name, model?.Id); + var list = model == null ? _transportTypeStorage.GetFullList() : _transportTypeStorage.GetFilteredList(model); + if (list == null) + { + _logger.LogWarning("ReadList return null list"); + return null; + } + _logger.LogInformation("ReadList. Count:{Count}", list.Count); + return list; + } + + public bool Update(TransportTypeBindingModel model) + { + CheckModel(model); + if (_transportTypeStorage.Update(model) == null) + { + _logger.LogWarning("Update operation failed"); + return false; + } + return true; + } + private void CheckModel(TransportTypeBindingModel model, bool withParams = true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) + { + return; + } + if (string.IsNullOrEmpty(model.Name)) + { + throw new ArgumentNullException("Нет названия ", nameof(model.Name)); + } + if (model.Price <= 0) + { + throw new ArgumentNullException("Цена должна быть больше 0", nameof(model.Price)); + } + _logger.LogInformation("TransportType. Name:{Name}. Price:{ Price}. Id: { Id}", model.Name, model.Price, model.Id); + var element = _transportTypeStorage.GetElement(new TransportTypeSearchModel + { + Name = model.Name + }); + if (element != null && element.Id != model.Id) + { + throw new InvalidOperationException("Type с таким названием уже есть"); + } + } + } +} diff --git a/RouteGuide/RouteGuideBusinessLogic/Class1.cs b/RouteGuide/RouteGuideBusinessLogic/Class1.cs new file mode 100644 index 0000000..3b748d5 --- /dev/null +++ b/RouteGuide/RouteGuideBusinessLogic/Class1.cs @@ -0,0 +1,7 @@ +namespace RouteGuideBusinessLogic +{ + public class Class1 + { + + } +} \ No newline at end of file diff --git a/RouteGuide/RouteGuideBusinessLogic/RouteGuideBusinessLogic.csproj b/RouteGuide/RouteGuideBusinessLogic/RouteGuideBusinessLogic.csproj new file mode 100644 index 0000000..be89c02 --- /dev/null +++ b/RouteGuide/RouteGuideBusinessLogic/RouteGuideBusinessLogic.csproj @@ -0,0 +1,17 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + diff --git a/RouteGuide/RouteGuideDatabaseImplement/Implements/RouteStorage.cs b/RouteGuide/RouteGuideDatabaseImplement/Implements/RouteStorage.cs new file mode 100644 index 0000000..81bcf1c --- /dev/null +++ b/RouteGuide/RouteGuideDatabaseImplement/Implements/RouteStorage.cs @@ -0,0 +1,112 @@ +using Microsoft.EntityFrameworkCore; +using RouteGuideContracts.BindingModels; +using RouteGuideContracts.SearchModels; +using RouteGuideContracts.StoragesModels; +using RouteGuideContracts.ViewModels; +using RouteGuideDatabaseImplements.Models; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RouteGuideDatabaseImplements.Implements +{ + public class RouteStorage : IRouteStorage + { + public RouteViewModel? Delete(RouteBindingModel model) + { + using var context = new RouteGuideDatabase(); + + var element = context.Routes.Include(x => x.Stops).FirstOrDefault(rec => rec.Id == model.Id); + + if (element != null) + { + context.Routes.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + + return null; + } + + public RouteViewModel? GetElement(RouteSearchModel model) + { + if (string.IsNullOrEmpty(model.Name) && !model.Id.HasValue) + { + return null; + } + + using var context = new RouteGuideDatabase(); + + return context.Routes.Include(x => x.Stops).ThenInclude(x => x.Stop).FirstOrDefault(x => (!string.IsNullOrEmpty(model.Name) && x.Name == model.Name) || (model.Id.HasValue && x.Id == model.Id))?.GetViewModel; + } + + public List GetFilteredList(RouteSearchModel model) + { + if (string.IsNullOrEmpty(model.Name)) + { + return new(); + } + + using var context = new RouteGuideDatabase(); + + return context.Routes.Include(x => x.Stops).ThenInclude(x => x.Stop).Where(x => x.Name.Contains(model.Name)).ToList().Select(x => x.GetViewModel).ToList(); + } + + public List GetFullList() + { + using var context = new RouteGuideDatabase(); + + return context.Routes.Include(x => x.Stops).ThenInclude(x => x.Stop).ToList().Select(x => x.GetViewModel).ToList(); + } + + public RouteViewModel? Insert(RouteBindingModel model) + { + using var context = new RouteGuideDatabase(); + + var newRoute = Route.Create(context, model); + + if (newRoute == null) + { + return null; + } + + context.Routes.Add(newRoute); + context.SaveChanges(); + + return newRoute.GetViewModel; + } + + public RouteViewModel? Update(RouteBindingModel model) + { + using var context = new RouteGuideDatabase(); + + using var transaction = context.Database.BeginTransaction(); + + try + { + var route = context.Routes.FirstOrDefault(rec => rec.Id == model.Id); + + if (route == null) + { + return null; + } + + route.Update(model); + context.SaveChanges(); + route.UpdateStops(context, model); + transaction.Commit(); + + return route.GetViewModel; + } + catch + { + transaction.Rollback(); + + throw; + } + } + } +} diff --git a/RouteGuide/RouteGuideDatabaseImplement/Implements/StopStorage.cs b/RouteGuide/RouteGuideDatabaseImplement/Implements/StopStorage.cs new file mode 100644 index 0000000..5146c71 --- /dev/null +++ b/RouteGuide/RouteGuideDatabaseImplement/Implements/StopStorage.cs @@ -0,0 +1,97 @@ +using RouteGuideContracts.BindingModels; +using RouteGuideContracts.SearchModels; +using RouteGuideContracts.StoragesModels; +using RouteGuideContracts.ViewModels; +using RouteGuideDatabaseImplements.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RouteGuideDatabaseImplements.Implements +{ + public class StopStorage : IStopStorage + { + public StopViewModel? Delete(StopBindingModel model) + { + using var context = new RouteGuideDatabase(); + + var element = context.Stops.FirstOrDefault(rec => rec.Id == model.Id); + + if (element != null) + { + context.Stops.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + + return null; + } + + public StopViewModel? GetElement(StopSearchModel model) + { + if (string.IsNullOrEmpty(model.Name) && !model.Id.HasValue) + { + return null; + } + + using var context = new RouteGuideDatabase(); + + return context.Stops.FirstOrDefault(x => (!string.IsNullOrEmpty(model.Name) && x.Name == model.Name) || (model.Id.HasValue && x.Id == model.Id))?.GetViewModel; + } + + public List GetFilteredList(StopSearchModel model) + { + if (string.IsNullOrEmpty(model.Name)) + { + return new(); + } + + using var context = new RouteGuideDatabase(); + + return context.Stops.Where(x => x.Name.Contains(model.Name)).Select(x => x.GetViewModel).ToList(); + } + + public List GetFullList() + { + using var context = new RouteGuideDatabase(); + + return context.Stops.Select(x => x.GetViewModel).ToList(); + } + + public StopViewModel? Insert(StopBindingModel model) + { + var newStop = Stop.Create(model); + + if (newStop == null) + { + return null; + } + + using var context = new RouteGuideDatabase(); + + context.Stops.Add(newStop); + context.SaveChanges(); + + return newStop.GetViewModel; + } + + public StopViewModel? Update(StopBindingModel model) + { + using var context = new RouteGuideDatabase(); + + var Stop = context.Stops.FirstOrDefault(x => x.Id == model.Id); + + if (Stop == null) + { + return null; + } + + Stop.Update(model); + context.SaveChanges(); + + return Stop.GetViewModel; + } + } +} diff --git a/RouteGuide/RouteGuideDatabaseImplement/Implements/TransportStorage.cs b/RouteGuide/RouteGuideDatabaseImplement/Implements/TransportStorage.cs new file mode 100644 index 0000000..43abc6a --- /dev/null +++ b/RouteGuide/RouteGuideDatabaseImplement/Implements/TransportStorage.cs @@ -0,0 +1,109 @@ +using RouteGuideContracts.BindingModels; +using RouteGuideContracts.SearchModels; +using RouteGuideContracts.StoragesModels; +using RouteGuideContracts.ViewModels; +using RouteGuideDatabaseImplements.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RouteGuideDatabaseImplements.Implements +{ + public class TransportStorage : ITransportStorage + { + public TransportViewModel? Delete(TransportBindingModel model) + { + using var context = new RouteGuideDatabase(); + + var element = context.Transports.FirstOrDefault(rec => rec.Id == model.Id); + + if (element != null) + { + context.Transports.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + + return null; + } + + public TransportViewModel? GetElement(TransportSearchModel model) + { + if (string.IsNullOrEmpty(model.DriverName) && !model.Id.HasValue) + { + return null; + } + + using var context = new RouteGuideDatabase(); + + return context.Transports.FirstOrDefault(x => (!string.IsNullOrEmpty(model.DriverName) && x.DriverName == model.DriverName) || (model.Id.HasValue && x.Id == model.Id))?.GetViewModel; + } + + public List GetFilteredList(TransportSearchModel model) + { + if (string.IsNullOrEmpty(model.DriverName)) + { + return new(); + } + + using var context = new RouteGuideDatabase(); + + return context.Transports.Where(x => x.DriverName.Contains(model.DriverName)).ToList().Select(x => x.GetViewModel).ToList(); + } + + public List GetFullList() + { + using var context = new RouteGuideDatabase(); + + return context.Transports.ToList().Select(x => x.GetViewModel).ToList(); + } + + public TransportViewModel? Insert(TransportBindingModel model) + { + using var context = new RouteGuideDatabase(); + + var newTransport = Transport.Create(model); + + if (newTransport == null) + { + return null; + } + + context.Transports.Add(newTransport); + context.SaveChanges(); + + return newTransport.GetViewModel; + } + + public TransportViewModel? Update(TransportBindingModel model) + { + using var context = new RouteGuideDatabase(); + + using var transaction = context.Database.BeginTransaction(); + + try + { + var transport = context.Transports.FirstOrDefault(rec => rec.Id == model.Id); + + if (transport == null) + { + return null; + } + + transport.Update(model); + context.SaveChanges(); + transaction.Commit(); + + return transport.GetViewModel; + } + catch + { + transaction.Rollback(); + + throw; + } + } + } +} diff --git a/RouteGuide/RouteGuideDatabaseImplement/Implements/TransportTypeStorage.cs b/RouteGuide/RouteGuideDatabaseImplement/Implements/TransportTypeStorage.cs new file mode 100644 index 0000000..c94c905 --- /dev/null +++ b/RouteGuide/RouteGuideDatabaseImplement/Implements/TransportTypeStorage.cs @@ -0,0 +1,109 @@ +using RouteGuideContracts.BindingModels; +using RouteGuideContracts.SearchModels; +using RouteGuideContracts.StoragesModels; +using RouteGuideContracts.ViewModels; +using RouteGuideDatabaseImplements.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RouteGuideDatabaseImplements.Implements +{ + public class TransportTypeStorage : ITransportTypeStorage + { + public TransportTypeViewModel? Delete(TransportTypeBindingModel model) + { + using var context = new RouteGuideDatabase(); + + var element = context.TransportTypes.FirstOrDefault(rec => rec.Id == model.Id); + + if (element != null) + { + context.TransportTypes.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + + return null; + } + + public TransportTypeViewModel? GetElement(TransportTypeSearchModel model) + { + if (string.IsNullOrEmpty(model.Name) && !model.Id.HasValue) + { + return null; + } + + using var context = new RouteGuideDatabase(); + + return context.TransportTypes.FirstOrDefault(x => (!string.IsNullOrEmpty(model.Name) && x.Name == model.Name) || (model.Id.HasValue && x.Id == model.Id))?.GetViewModel; + } + + public List GetFilteredList(TransportTypeSearchModel model) + { + if (string.IsNullOrEmpty(model.Name)) + { + return new(); + } + + using var context = new RouteGuideDatabase(); + + return context.TransportTypes.Where(x => x.Name.Contains(model.Name)).ToList().Select(x => x.GetViewModel).ToList(); + } + + public List GetFullList() + { + using var context = new RouteGuideDatabase(); + + return context.TransportTypes.ToList().Select(x => x.GetViewModel).ToList(); + } + + public TransportTypeViewModel? Insert(TransportTypeBindingModel model) + { + using var context = new RouteGuideDatabase(); + + var newTransportType = TransportType.Create(model); + + if (newTransportType == null) + { + return null; + } + + context.TransportTypes.Add(newTransportType); + context.SaveChanges(); + + return newTransportType.GetViewModel; + } + + public TransportTypeViewModel? Update(TransportTypeBindingModel model) + { + using var context = new RouteGuideDatabase(); + + using var transaction = context.Database.BeginTransaction(); + + try + { + var transportType = context.TransportTypes.FirstOrDefault(rec => rec.Id == model.Id); + + if (transportType == null) + { + return null; + } + + transportType.Update(model); + context.SaveChanges(); + transaction.Commit(); + + return transportType.GetViewModel; + } + catch + { + transaction.Rollback(); + + throw; + } + } + } +} diff --git a/RouteGuide/RouteGuideDatabaseImplement/Models/Route.cs b/RouteGuide/RouteGuideDatabaseImplement/Models/Route.cs new file mode 100644 index 0000000..d6ab0e7 --- /dev/null +++ b/RouteGuide/RouteGuideDatabaseImplement/Models/Route.cs @@ -0,0 +1,106 @@ +using RouteGuideContracts.BindingModels; +using RouteGuideContracts.ViewModels; +using RouteGuideDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RouteGuideDatabaseImplements.Models +{ + public class Route : IRouteModel + { + public int Id { get; private set; } + + [Required] + public string Name { get; private set; } = string.Empty; + + Dictionary? _routeStops = null; + + [NotMapped] + public Dictionary RouteStops + { + get + { + if (_routeStops == null) + { + _routeStops = Stops.ToDictionary(recPC => recPC.StopId, recPC => (recPC.Stop as IStopModel, recPC.Number)); + } + return _routeStops; + } + + } + + [ForeignKey("RouteId")] + public virtual List Stops { get; set; } = new(); + + public static Route Create(RouteGuideDatabase context, RouteBindingModel model) + { + return new Route() + { + Id = model.Id, + Name = model.Name, + Stops = model.RouteStops.Select(x => new RouteStop + { + Stop = context.Stops.First(y => y.Id == x.Key), + Number = x.Value.Item2 + }).ToList() + }; + } + + public void Update(RouteBindingModel model) + { + Name = model.Name; + } + + public RouteViewModel GetViewModel + { + get + { + using var context = new RouteGuideDatabase(); + return new RouteViewModel + { + Id = Id, + Name = Name, + RouteStops = RouteStops + }; + } + } + + public void UpdateStops(RouteGuideDatabase context, RouteBindingModel model) + { + var routeStops = context.RoutesStops.Where(rec => rec.RouteId == model.Id).ToList(); + + if (routeStops != null && routeStops.Count > 0) + { // удалили те, которых нет в модели + context.RoutesStops.RemoveRange(routeStops.Where(rec => !model.RouteStops.ContainsKey(rec.StopId))); + context.SaveChanges(); + // обновили количество у существующих записей + foreach (var updateStop in routeStops) + { + updateStop.Number = model.RouteStops[updateStop.StopId].Item2; + model.RouteStops.Remove(updateStop.StopId); + } + context.SaveChanges(); + } + + var route = context.Routes.First(x => x.Id == Id); + + foreach (var pc in model.RouteStops) + { + context.RoutesStops.Add(new RouteStop + { + Route = route, + Stop = context.Stops.First(x => x.Id == pc.Key), + Number = pc.Value.Item2 + }); + context.SaveChanges(); + } + _routeStops = null; + } + + } +} diff --git a/RouteGuide/RouteGuideDatabaseImplement/Models/RouteStop.cs b/RouteGuide/RouteGuideDatabaseImplement/Models/RouteStop.cs new file mode 100644 index 0000000..ae0f3ab --- /dev/null +++ b/RouteGuide/RouteGuideDatabaseImplement/Models/RouteStop.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RouteGuideDatabaseImplements.Models +{ + public class RouteStop + { + public int Id { get; set; } + + [Required] + public int StopId { get; set; } + + [Required] + public int RouteId { get; set; } + + [Required] + public int Number { get; set; } + + public virtual Route Route { get; set; } = new(); + public virtual Stop Stop { get; set; } = new(); + } +} diff --git a/RouteGuide/RouteGuideDatabaseImplement/Models/Stop.cs b/RouteGuide/RouteGuideDatabaseImplement/Models/Stop.cs new file mode 100644 index 0000000..c7fa7ae --- /dev/null +++ b/RouteGuide/RouteGuideDatabaseImplement/Models/Stop.cs @@ -0,0 +1,58 @@ +using RouteGuideContracts.BindingModels; +using RouteGuideContracts.ViewModels; +using RouteGuideDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RouteGuideDatabaseImplements.Models +{ + public class Stop : IStopModel + { + public int Id { get; private set; } + + [Required] + public string Name { get; private set; } = string.Empty; + + [ForeignKey("StopId")] + public virtual List RoutesStops { get; set; } = new(); + + public static Stop? Create(StopBindingModel model) + { + if (model == null) + { + return null; + } + return new Stop() + { + Id = model.Id, + Name = model.Name, + }; + } + public static Stop Create(StopViewModel model) + { + return new Stop + { + Id = model.Id, + Name = model.Name, + }; + } + public void Update(StopBindingModel model) + { + if (model == null) + { + return; + } + Name = model.Name; + } + public StopViewModel GetViewModel => new() + { + Id = Id, + Name = Name, + }; + } +} diff --git a/RouteGuide/RouteGuideDatabaseImplement/Models/Transport.cs b/RouteGuide/RouteGuideDatabaseImplement/Models/Transport.cs new file mode 100644 index 0000000..8804b72 --- /dev/null +++ b/RouteGuide/RouteGuideDatabaseImplement/Models/Transport.cs @@ -0,0 +1,71 @@ +using RouteGuideContracts.BindingModels; +using RouteGuideContracts.ViewModels; +using RouteGuideDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RouteGuideDatabaseImplements.Models +{ + public class Transport : ITransportModel + { + public int Id { get; private set; } + + [Required] + public string DriverName { get; private set; } = string.Empty; + + [Required] + public int RouteId { get; set; } + + [Required] + public int TransportTypeId { get; set; } + + public static Transport? Create(TransportBindingModel model) + { + if (model == null) + { + return null; + } + return new Transport() + { + Id = model.Id, + DriverName = model.DriverName, + RouteId = model.RouteId, + TransportTypeId = model.TransportTypeId + }; + } + + public static Transport Create(TransportViewModel model) + { + return new Transport + { + Id = model.Id, + DriverName = model.DriverName, + RouteId = model.RouteId, + TransportTypeId = model.TransportTypeId + }; + } + + public void Update(TransportBindingModel model) + { + if (model == null) + { + return; + } + DriverName = model.DriverName; + RouteId = model.RouteId; + } + + public TransportViewModel GetViewModel => new() + { + Id = Id, + DriverName = DriverName, + RouteId = RouteId, + TransportTypeId = TransportTypeId + }; + } +} diff --git a/RouteGuide/RouteGuideDatabaseImplement/Models/TransportType.cs b/RouteGuide/RouteGuideDatabaseImplement/Models/TransportType.cs new file mode 100644 index 0000000..98e2f99 --- /dev/null +++ b/RouteGuide/RouteGuideDatabaseImplement/Models/TransportType.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RouteGuideContracts.BindingModels; +using RouteGuideContracts.ViewModels; +using RouteGuideDataModels.Models; + +namespace RouteGuideDatabaseImplements.Models +{ + public class TransportType : ITransportTypeModel + { + public int Id { get; private set; } + + [Required] + public string Name { get; private set; } = string.Empty; + + [Required] + public double Price { get; set; } + + [ForeignKey("TransportTypeId")] + public virtual List Transports { get; set; } = new(); + + + public static TransportType? Create(TransportTypeBindingModel model) + { + if (model == null) + { + return null; + } + return new TransportType() + { + Id = model.Id, + Name = model.Name, + Price = model.Price + }; + } + + public static TransportType Create(TransportTypeViewModel model) + { + return new TransportType + { + Id = model.Id, + Name = model.Name, + Price = model.Price + }; + } + + public void Update(TransportTypeBindingModel model) + { + if (model == null) + { + return; + } + Name = model.Name; + Price = model.Price; + } + + public TransportTypeViewModel GetViewModel => new() + { + Id = Id, + Name = Name, + Price = Price + }; + } +} diff --git a/RouteGuide/RouteGuideDatabaseImplement/RouteGuideDatabase.cs b/RouteGuide/RouteGuideDatabaseImplement/RouteGuideDatabase.cs new file mode 100644 index 0000000..8dd5e20 --- /dev/null +++ b/RouteGuide/RouteGuideDatabaseImplement/RouteGuideDatabase.cs @@ -0,0 +1,26 @@ +using Microsoft.EntityFrameworkCore; +using RouteGuideDatabaseImplements.Models; +using System.Configuration; + +namespace RouteGuideDatabaseImplements +{ + public class RouteGuideDatabase : DbContext + { + string dbName = ConfigurationManager.AppSettings["connectToDb"]; + + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (optionsBuilder.IsConfigured == false) + { + optionsBuilder.UseNpgsql(dbName); + } + base.OnConfiguring(optionsBuilder); + } + public virtual DbSet Routes { set; get; } + public virtual DbSet Stops { set; get; } + public virtual DbSet RoutesStops { set; get; } + public virtual DbSet TransportTypes { set; get; } + public virtual DbSet Transports { set; get; } + } +} \ No newline at end of file diff --git a/RouteGuide/RouteGuideDatabaseImplement/RouteGuideDatabaseImplements.csproj b/RouteGuide/RouteGuideDatabaseImplement/RouteGuideDatabaseImplements.csproj new file mode 100644 index 0000000..c1e65c1 --- /dev/null +++ b/RouteGuide/RouteGuideDatabaseImplement/RouteGuideDatabaseImplements.csproj @@ -0,0 +1,19 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + +