Реализация хранилищ

This commit is contained in:
Володя 2023-05-02 11:50:43 +03:00
parent ed1504beb1
commit ec67110d7c
9 changed files with 710 additions and 2 deletions

View File

@ -109,7 +109,7 @@ namespace AutomobilePlant
{
Id = _id ?? 0,
ShopName = ShopNameTextBox.Text,
DateOpen = DateOpenPicker.Value,
DateOpen = DateTime.SpecifyKind(DateOpenPicker.Value, DateTimeKind.Utc) ,
Adress = AdressTextBox.Text,
Fullness = (int)FullnessnumericUpDown.Value,
Cars = _cars

View File

@ -15,7 +15,7 @@ namespace AutomobilePlantDataBaseImplements
{
if (optionsBuilder.IsConfigured == false)
{
optionsBuilder.UseNpgsql("Server=PostgreSQL;Host=localhost;Port=5432;Database=AutoPlantDataBase;Username=postgres;Password=postgres");
optionsBuilder.UseNpgsql("Server=PostgreSQL;Host=localhost;Port=5432;Database=AutoPlantDataBaseHard;Username=postgres;Password=postgres");
}
base.OnConfiguring(optionsBuilder);
}
@ -27,5 +27,7 @@ namespace AutomobilePlantDataBaseImplements
public virtual DbSet<CarComponent> CarComponents { set; get; }
public virtual DbSet<Order> Orders { set; get; }
public virtual DbSet<CarShop> CarShops { set; get; }
public virtual DbSet<ShopCar> ShopCars { get; set; }
}
}

View File

@ -0,0 +1,158 @@
using AutomobilePlantContracts.BindingModels;
using AutomobilePlantContracts.SearchModel;
using AutomobilePlantContracts.StoragesContracts;
using AutomobilePlantContracts.ViewModel;
using AutomobilePlantDataBaseImplements.Models;
using AutomobilePlantDataModels.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AutomobilePlantDataBaseImplements.Implements
{
public class CarShopStorage : ICarShopStorage
{
public CarShopViewModel? Delete(CarShopBindingModel model)
{
using var context = new AutoPlantDataBase();
var element = context.CarShops
.Include(x => x.ShopCars)
.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.CarShops.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
public CarShopViewModel? GetElement(CarShopSearchModel model)
{
if (string.IsNullOrEmpty(model.ShopName) && !model.Id.HasValue)
{
return null;
}
using var context = new AutoPlantDataBase();
return context.CarShops
.Include(x => x.ShopCars)
.ThenInclude(x => x.Car)
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.ShopName) && x.ShopName.Contains(model.ShopName)) ||
(model.Id.HasValue && x.Id == model.Id))
?.GetViewModel;
}
public List<CarShopViewModel> GetFilteredList(CarShopSearchModel model)
{
if (string.IsNullOrEmpty(model.ShopName))
{
return new();
}
using var context = new AutoPlantDataBase();
return context.CarShops
.Include(x => x.ShopCars)
.ThenInclude(x => x.Car)
.Where(x => x.ShopName.Contains(model.ShopName))
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
public List<CarShopViewModel> GetFullList()
{
using var context = new AutoPlantDataBase();
return context.CarShops
.Include(x => x.ShopCars)
.ThenInclude(x => x.Car)
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
public CarShopViewModel? Insert(CarShopBindingModel model)
{
using var context = new AutoPlantDataBase();
var newShop = CarShop.Create(context, model);
if (newShop == null)
{
return null;
}
context.CarShops.Add(newShop);
context.SaveChanges();
return newShop.GetViewModel;
}
public bool TrySell(ICarModel car, int quantity)
{
using var context = new AutoPlantDataBase();
using var transaction = context.Database.BeginTransaction();
var shops = GetFullList();
try
{
for(int i = 0;quantity > 0; i++)
{
if (shops[i].Cars.ContainsKey(car.Id))
{
if (shops[i].Cars[car.Id].Item2 > quantity)
{
shops[i].Cars[car.Id] = (shops[i].Cars[car.Id].Item1, shops[i].Cars[car.Id].Item2 - quantity);
quantity = 0;
}
else
{
quantity -= shops[i].Cars[car.Id].Item2;
shops[i].Cars.Remove(car.Id);
}
Update(new CarShopBindingModel
{
ShopName = shops[i].ShopName,
Adress = shops[i].Adress,
DateOpen = shops[i].DateOpen,
Fullness = shops[i].Fullness,
Id = shops[i].Id,
Cars = shops[i].Cars,
});
}
}
transaction.Commit();
return true;
}
catch
{
transaction.Rollback();
throw;
}
throw new NotImplementedException();
}
public CarShopViewModel? Update(CarShopBindingModel model)
{
using var context = new AutoPlantDataBase();
using var transaction = context.Database.BeginTransaction();
try
{
var shop = context.CarShops.FirstOrDefault(rec => rec.Id == model.Id);
if (shop == null)
{
return null;
}
shop.Update(model);
context.SaveChanges();
shop.UpdateCars(context, model);
transaction.Commit();
return shop.GetViewModel;
}
catch
{
transaction.Rollback();
throw;
}
}
}
}

View File

@ -0,0 +1,254 @@
// <auto-generated />
using System;
using AutomobilePlantDataBaseImplements;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace AutomobilePlantDataBaseImplements.Migrations
{
[DbContext(typeof(AutoPlantDataBase))]
[Migration("20230502080521_Shops")]
partial class Shops
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.5")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Car", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("CarName")
.IsRequired()
.HasColumnType("text");
b.Property<double>("Price")
.HasColumnType("double precision");
b.HasKey("Id");
b.ToTable("Cars");
});
modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.CarComponent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("CarId")
.HasColumnType("integer");
b.Property<int>("ComponentId")
.HasColumnType("integer");
b.Property<int>("Count")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CarId");
b.HasIndex("ComponentId");
b.ToTable("CarComponents");
});
modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.CarShop", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Adress")
.IsRequired()
.HasColumnType("text");
b.Property<DateTime>("DateOpen")
.HasColumnType("timestamp with time zone");
b.Property<int>("Fullness")
.HasColumnType("integer");
b.Property<string>("ShopName")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CarShops");
});
modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Component", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ComponentName")
.IsRequired()
.HasColumnType("text");
b.Property<double>("Cost")
.HasColumnType("double precision");
b.HasKey("Id");
b.ToTable("Components");
});
modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("CarId")
.HasColumnType("integer");
b.Property<string>("CarName")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Count")
.HasColumnType("integer");
b.Property<DateTime>("DateCreate")
.HasColumnType("timestamp with time zone");
b.Property<DateTime?>("DateImplement")
.HasColumnType("timestamp with time zone");
b.Property<int>("Status")
.HasColumnType("integer");
b.Property<double>("Sum")
.HasColumnType("double precision");
b.HasKey("Id");
b.HasIndex("CarId");
b.ToTable("Orders");
});
modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.ShopCar", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("CarId")
.HasColumnType("integer");
b.Property<int>("Count")
.HasColumnType("integer");
b.Property<int>("ShopId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CarId");
b.HasIndex("ShopId");
b.ToTable("ShopCars");
});
modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.CarComponent", b =>
{
b.HasOne("AutomobilePlantDataBaseImplements.Models.Car", "Car")
.WithMany("Components")
.HasForeignKey("CarId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AutomobilePlantDataBaseImplements.Models.Component", "Component")
.WithMany("CarComponents")
.HasForeignKey("ComponentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Car");
b.Navigation("Component");
});
modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Order", b =>
{
b.HasOne("AutomobilePlantDataBaseImplements.Models.Car", "car")
.WithMany("Orders")
.HasForeignKey("CarId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("car");
});
modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.ShopCar", b =>
{
b.HasOne("AutomobilePlantDataBaseImplements.Models.Car", "Car")
.WithMany("ShopCars")
.HasForeignKey("CarId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AutomobilePlantDataBaseImplements.Models.CarShop", "CarShop")
.WithMany("ShopCars")
.HasForeignKey("ShopId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Car");
b.Navigation("CarShop");
});
modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Car", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
b.Navigation("ShopCars");
});
modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.CarShop", b =>
{
b.Navigation("ShopCars");
});
modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Component", b =>
{
b.Navigation("CarComponents");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,79 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace AutomobilePlantDataBaseImplements.Migrations
{
/// <inheritdoc />
public partial class Shops : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "CarShops",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
ShopName = table.Column<string>(type: "text", nullable: false),
Adress = table.Column<string>(type: "text", nullable: false),
DateOpen = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
Fullness = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_CarShops", x => x.Id);
});
migrationBuilder.CreateTable(
name: "ShopCars",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
ShopId = table.Column<int>(type: "integer", nullable: false),
CarId = table.Column<int>(type: "integer", nullable: false),
Count = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ShopCars", x => x.Id);
table.ForeignKey(
name: "FK_ShopCars_CarShops_ShopId",
column: x => x.ShopId,
principalTable: "CarShops",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ShopCars_Cars_CarId",
column: x => x.CarId,
principalTable: "Cars",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_ShopCars_CarId",
table: "ShopCars",
column: "CarId");
migrationBuilder.CreateIndex(
name: "IX_ShopCars_ShopId",
table: "ShopCars",
column: "ShopId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "ShopCars");
migrationBuilder.DropTable(
name: "CarShops");
}
}
}

View File

@ -68,6 +68,33 @@ namespace AutomobilePlantDataBaseImplements.Migrations
b.ToTable("CarComponents");
});
modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.CarShop", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Adress")
.IsRequired()
.HasColumnType("text");
b.Property<DateTime>("DateOpen")
.HasColumnType("timestamp with time zone");
b.Property<int>("Fullness")
.HasColumnType("integer");
b.Property<string>("ShopName")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CarShops");
});
modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Component", b =>
{
b.Property<int>("Id")
@ -125,6 +152,32 @@ namespace AutomobilePlantDataBaseImplements.Migrations
b.ToTable("Orders");
});
modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.ShopCar", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("CarId")
.HasColumnType("integer");
b.Property<int>("Count")
.HasColumnType("integer");
b.Property<int>("ShopId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CarId");
b.HasIndex("ShopId");
b.ToTable("ShopCars");
});
modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.CarComponent", b =>
{
b.HasOne("AutomobilePlantDataBaseImplements.Models.Car", "Car")
@ -155,11 +208,37 @@ namespace AutomobilePlantDataBaseImplements.Migrations
b.Navigation("car");
});
modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.ShopCar", b =>
{
b.HasOne("AutomobilePlantDataBaseImplements.Models.Car", "Car")
.WithMany("ShopCars")
.HasForeignKey("CarId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AutomobilePlantDataBaseImplements.Models.CarShop", "CarShop")
.WithMany("ShopCars")
.HasForeignKey("ShopId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Car");
b.Navigation("CarShop");
});
modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Car", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
b.Navigation("ShopCars");
});
modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.CarShop", b =>
{
b.Navigation("ShopCars");
});
modelBuilder.Entity("AutomobilePlantDataBaseImplements.Models.Component", b =>

View File

@ -42,6 +42,8 @@ namespace AutomobilePlantDataBaseImplements.Models
[ForeignKey("CarId")]
public virtual List<Order> Orders { get; set; } = new();
[ForeignKey("CarId")]
public virtual List<ShopCar> ShopCars { get; set; } = new();
public static Car Create(AutoPlantDataBase context, CarBindingModel model)
{

View File

@ -0,0 +1,107 @@
using AutomobilePlantContracts.BindingModels;
using AutomobilePlantContracts.ViewModel;
using AutomobilePlantDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AutomobilePlantDataBaseImplements.Models
{
public class CarShop : ICarShop
{
[Required]
public string ShopName { get; set; } = string.Empty;
[Required]
public string Adress { get; set; } = string.Empty;
[Required]
public DateTime DateOpen { get; set; }
[Required]
public int Fullness { get; set; }
public Dictionary<int, (ICarModel, int)> _ShopCars = null;
[NotMapped]
public Dictionary<int, (ICarModel, int)> Cars
{
get
{
if (_ShopCars == null)
{
_ShopCars = ShopCars
.ToDictionary(recPC => recPC.CarId, recPC => (recPC.Car as ICarModel, recPC.Count));
}
return _ShopCars;
}
}
public int Id { get; set; }
[ForeignKey("ShopId")]
public virtual List<ShopCar> ShopCars { get; set; } = new();
public static CarShop Create(AutoPlantDataBase context, CarShopBindingModel model)
{
return new CarShop()
{
Id = model.Id,
ShopName = model.ShopName,
Adress = model.Adress,
DateOpen = model.DateOpen,
Fullness = model.Fullness,
ShopCars = model.Cars.Select(x => new ShopCar
{
Car = context.Cars.First(y => y.Id == x.Key),
Count = x.Value.Item2
}).ToList()
};
}
public void Update(CarShopBindingModel model)
{
ShopName = model.ShopName;
Adress = model.Adress;
Fullness = model.Fullness;
}
public CarShopViewModel GetViewModel => new()
{
Id = Id,
ShopName = ShopName,
Adress = Adress,
DateOpen = DateOpen,
Fullness = Fullness,
Cars = Cars
};
public void UpdateCars(AutoPlantDataBase context, CarShopBindingModel model)
{
var shopCars = context.ShopCars.Where(rec => rec.ShopId == model.Id).ToList();
if (shopCars != null && shopCars.Count > 0)
{
context.ShopCars.RemoveRange(shopCars.Where(rec => !model.Cars.ContainsKey(rec.CarId)));
context.SaveChanges();
}
foreach (var updateCar in shopCars)
{
updateCar.Count = model.Cars[updateCar.CarId].Item2;
model.Cars.Remove(updateCar.CarId);
}
context.SaveChanges();
var shop = context.CarShops.First(x => x.Id == Id);
foreach (var pc in model.Cars)
{
context.ShopCars.Add(new ShopCar
{
CarShop = shop,
Car = context.Cars.First(x => x.Id == pc.Key),
Count = pc.Value.Item2
});
context.SaveChanges();
}
_ShopCars = null;
}
}
}

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AutomobilePlantDataBaseImplements.Models
{
public class ShopCar
{
public int Id { get; set; }
[Required]
public int ShopId { get; set; }
[Required]
public int CarId { get; set; }
[Required]
public int Count { get; set; }
public virtual CarShop CarShop { get; set; } = new();
public virtual Car Car { get; set; } = new();
}
}