lab3-hard-to-lab4-hard #8

Closed
Salikh wants to merge 14 commits from lab3-hard into laba4-hard
11 changed files with 495 additions and 14 deletions
Showing only changes of commit dcef17c190 - Show all commits

View File

@ -0,0 +1,144 @@
using Microsoft.EntityFrameworkCore;
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.SearchModels;
using MotorPlantContracts.StoragesContracts;
using MotorPlantContracts.ViewModels;
using MotorPlantDatabaseImplement.Models;
using MotorPlantDataModels.Models;
namespace MotorPlantDatabaseImplement.Implements
{
public class ShopStorage : IShopStorage
{
public ShopViewModel? Delete(ShopBindingModel model)
{
using var context = new MotorPlantDatabase();
var element = context.Shops.FirstOrDefault(x => x.Id == model.Id);
if (element != null)
{
context.Shops.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
public ShopViewModel? GetElement(ShopSearchModel model)
{
if (string.IsNullOrEmpty(model.Name) && !model.Id.HasValue)
{
return null;
}
using var context = new MotorPlantDatabase();
return context.Shops.Include(x => x.Engines).ThenInclude(x => x.Engine).FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)?.GetViewModel;
}
public List<ShopViewModel> GetFilteredList(ShopSearchModel model)
{
if (string.IsNullOrEmpty(model.Name))
{
return new();
}
using var context = new MotorPlantDatabase();
return context.Shops
.Include(x => x.Engines)
.ThenInclude(x => x.Engine)
.Select(x => x.GetViewModel)
.Where(x => x.ShopName.Contains(model.Name ?? string.Empty))
.ToList();
}
public List<ShopViewModel> GetFullList()
{
using var context = new MotorPlantDatabase();
return context.Shops
.Include(x => x.Engines)
.ThenInclude(x => x.Engine)
.Select(x => x.GetViewModel)
.ToList();
}
public ShopViewModel? Insert(ShopBindingModel model)
{
using var context = new MotorPlantDatabase();
try
{
var newShop = Shop.Create(context, model);
if (newShop == null)
{
return null;
}
if (context.Shops.Any(x => x.ShopName == newShop.ShopName))
{
throw new Exception("Не должно быть два магазина с одним названием");
}
context.Shops.Add(newShop);
context.SaveChanges();
return newShop.GetViewModel;
}
catch
{
throw;
}
}
public ShopViewModel? Update(ShopBindingModel model)
{
using var context = new MotorPlantDatabase();
var shop = context.Shops.FirstOrDefault(x => x.Id == model.Id);
if (shop == null)
{
return null;
}
try
{
if (context.Shops.Any(x => (x.ShopName == model.ShopName && x.Id != model.Id)))
{
throw new Exception("Не должно быть два магазина с одним названием");
}
shop.Update(model);
shop.UpdateDresses(context, model);
context.SaveChanges();
return shop.GetViewModel;
}
catch
{
throw;
}
}
public bool SellEngines(IEngineModel model, int count)
{
if (model == null)
return false;
using var context = new MotorPlantDatabase();
using var transaction = context.Database.BeginTransaction();
List<ShopEngine> lst = new List<ShopEngine>();
foreach (var el in context.ShopEngines.Where(x => x.EngineId == model.Id))
{
int dif = count;
if (el.Count < dif)
dif = el.Count;
el.Count -= dif;
count -= dif;
if (el.Count == 0)
{
lst.Add(el);
}
if (count == 0)
break;
}
if (count > 0)
{
transaction.Rollback();
return false;
}
foreach (var el in lst)
{
context.ShopEngines.Remove(el);
}
context.SaveChanges();
transaction.Commit();
return true;
}
}
}

View File

@ -12,8 +12,8 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace MotorPlantDatabaseImplement.Migrations
{
[DbContext(typeof(MotorPlantDatabase))]
[Migration("20240403225731_InitMigration")]
partial class InitMigration
[Migration("20240411122818_InitHardMigration")]
partial class InitHardMigration
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -124,6 +124,59 @@ namespace MotorPlantDatabaseImplement.Migrations
b.ToTable("Orders");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Shop", 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 without time zone");
b.Property<int>("MaxCount")
.HasColumnType("integer");
b.Property<string>("ShopName")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Shops");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.ShopEngine", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("integer");
b.Property<int>("EngineId")
.HasColumnType("integer");
b.Property<int>("ShopId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("EngineId");
b.HasIndex("ShopId");
b.ToTable("ShopEngines");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.EngineComponent", b =>
{
b.HasOne("MotorPlantDatabaseImplement.Models.Component", "Component")
@ -154,6 +207,25 @@ namespace MotorPlantDatabaseImplement.Migrations
b.Navigation("Engine");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.ShopEngine", b =>
{
b.HasOne("MotorPlantDatabaseImplement.Models.Engine", "Engine")
.WithMany()
.HasForeignKey("EngineId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MotorPlantDatabaseImplement.Models.Shop", "Shop")
.WithMany("Engines")
.HasForeignKey("ShopId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Engine");
b.Navigation("Shop");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Component", b =>
{
b.Navigation("EngineComponents");
@ -165,6 +237,11 @@ namespace MotorPlantDatabaseImplement.Migrations
b.Navigation("Orders");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Shop", b =>
{
b.Navigation("Engines");
});
#pragma warning restore 612, 618
}
}

View File

@ -7,7 +7,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace MotorPlantDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class InitMigration : Migration
public partial class InitHardMigration : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
@ -40,6 +40,22 @@ namespace MotorPlantDatabaseImplement.Migrations
table.PrimaryKey("PK_Engines", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Shops",
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 without time zone", nullable: false),
MaxCount = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Shops", x => x.Id);
});
migrationBuilder.CreateTable(
name: "EngineComponents",
columns: table => new
@ -91,6 +107,33 @@ namespace MotorPlantDatabaseImplement.Migrations
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ShopEngines",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
EngineId = table.Column<int>(type: "integer", nullable: false),
ShopId = table.Column<int>(type: "integer", nullable: false),
Count = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ShopEngines", x => x.Id);
table.ForeignKey(
name: "FK_ShopEngines_Engines_EngineId",
column: x => x.EngineId,
principalTable: "Engines",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ShopEngines_Shops_ShopId",
column: x => x.ShopId,
principalTable: "Shops",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_EngineComponents_ComponentId",
table: "EngineComponents",
@ -105,6 +148,16 @@ namespace MotorPlantDatabaseImplement.Migrations
name: "IX_Orders_EngineId",
table: "Orders",
column: "EngineId");
migrationBuilder.CreateIndex(
name: "IX_ShopEngines_EngineId",
table: "ShopEngines",
column: "EngineId");
migrationBuilder.CreateIndex(
name: "IX_ShopEngines_ShopId",
table: "ShopEngines",
column: "ShopId");
}
/// <inheritdoc />
@ -116,11 +169,17 @@ namespace MotorPlantDatabaseImplement.Migrations
migrationBuilder.DropTable(
name: "Orders");
migrationBuilder.DropTable(
name: "ShopEngines");
migrationBuilder.DropTable(
name: "Components");
migrationBuilder.DropTable(
name: "Engines");
migrationBuilder.DropTable(
name: "Shops");
}
}
}

View File

@ -121,6 +121,59 @@ namespace MotorPlantDatabaseImplement.Migrations
b.ToTable("Orders");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Shop", 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 without time zone");
b.Property<int>("MaxCount")
.HasColumnType("integer");
b.Property<string>("ShopName")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Shops");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.ShopEngine", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("integer");
b.Property<int>("EngineId")
.HasColumnType("integer");
b.Property<int>("ShopId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("EngineId");
b.HasIndex("ShopId");
b.ToTable("ShopEngines");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.EngineComponent", b =>
{
b.HasOne("MotorPlantDatabaseImplement.Models.Component", "Component")
@ -151,6 +204,25 @@ namespace MotorPlantDatabaseImplement.Migrations
b.Navigation("Engine");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.ShopEngine", b =>
{
b.HasOne("MotorPlantDatabaseImplement.Models.Engine", "Engine")
.WithMany()
.HasForeignKey("EngineId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MotorPlantDatabaseImplement.Models.Shop", "Shop")
.WithMany("Engines")
.HasForeignKey("ShopId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Engine");
b.Navigation("Shop");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Component", b =>
{
b.Navigation("EngineComponents");
@ -162,6 +234,11 @@ namespace MotorPlantDatabaseImplement.Migrations
b.Navigation("Orders");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Shop", b =>
{
b.Navigation("Engines");
});
#pragma warning restore 612, 618
}
}

View File

@ -43,7 +43,6 @@ namespace MotorPlantDatabaseImplement.Models
Sum = model.Sum,
Status = model.Status,
DateCreate = model.DateCreate,
DateImplement = model.DateImplement
};
}
@ -66,7 +65,6 @@ namespace MotorPlantDatabaseImplement.Models
Status = Status,
DateCreate = DateCreate,
DateImplement = DateImplement,
EngineName = Engine.EngineName
};
}
}

View File

@ -0,0 +1,105 @@
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.ViewModels;
using MotorPlantDataModels.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 MotorPlantDatabaseImplement.Models
{
public class Shop : IShopModel
{
public int Id { get; private set; }
[Required]
public string ShopName { get; private set; }
[Required]
public string Adress { get; private set; }
[Required]
public DateTime DateOpen { get; private set; }
[Required]
public int MaxCount { get; private set; }
private Dictionary<int, (IEngineModel, int)>? _shopEngines = null;
[NotMapped]
public Dictionary<int, (IEngineModel, int)>? ShopEngines
{
get
{
if (_shopEngines == null)
{
_shopEngines = Engines.ToDictionary(x => x.EngineId, x => (x.Engine as IEngineModel, x.Count));
}
return _shopEngines;
}
}
[ForeignKey("ShopId")]
public virtual List<ShopEngine> Engines { get; set; } = new();
public static Shop? Create(MotorPlantDatabase context, ShopBindingModel model)
{
if (model == null)
return null;
return new Shop()
{
Id = model.Id,
ShopName = model.ShopName,
Adress = model.Adress,
DateOpen = model.DateOpen,
MaxCount = model.MaxCount,
Engines = model.ShopEngines.Select(x => new ShopEngine
{
Engine = context.Engines.First(y => y.Id == x.Key),
Count = x.Value.Item2
}).ToList()
};
}
public void Update(ShopBindingModel? model)
{
if (model == null)
return;
ShopName = model.ShopName;
Adress = model.Adress;
DateOpen = model.DateOpen;
MaxCount = model.MaxCount;
}
public ShopViewModel GetViewModel => new()
{
Id = Id,
ShopName = ShopName,
Adress = Adress,
DateOpen = DateOpen,
MaxCount = MaxCount,
ShopEngines = ShopEngines
};
public void UpdateDresses(MotorPlantDatabase context, ShopBindingModel model)
{
var shopEngines = context.ShopEngines.Where(rec => rec.ShopId == model.Id).ToList();
if (shopEngines != null && shopEngines.Count > 0)
{
context.ShopEngines.RemoveRange(shopEngines.Where(rec => !model.ShopEngines.ContainsKey(rec.EngineId)));
context.SaveChanges();
foreach (var uEngine in shopEngines)
{
uEngine.Count = model.ShopEngines[uEngine.EngineId].Item2;
model.ShopEngines.Remove(uEngine.EngineId);
}
context.SaveChanges();
}
var shop = context.Shops.First(x => x.Id == Id);
foreach (var pc in model.ShopEngines)
{
context.ShopEngines.Add(new ShopEngine
{
Shop = shop,
Engine = context.Engines.First(x => x.Id == pc.Key),
Count = pc.Value.Item2
});
context.SaveChanges();
}
_shopEngines = null;
}
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MotorPlantDatabaseImplement.Models
{
public class ShopEngine
{
public int Id { get; set; }
[Required]
public int EngineId { get; set; }
[Required]
public int ShopId { get; set; }
[Required]
public int Count { get; set; }
public virtual Shop Shop { get; set; } = new();
public virtual Engine Engine { get; set; } = new();
}
}

View File

@ -9,7 +9,7 @@ namespace MotorPlantDatabaseImplement
{
if (optionsBuilder.IsConfigured == false)
{
optionsBuilder.UseNpgsql(@"Host=localhost;Port=5432;Database=MotorPlant_db;Username=postgres;Password=admin");
optionsBuilder.UseNpgsql(@"Host=localhost;Port=5432;Database=MotorPlantHard_db;Username=postgres;Password=admin");
}
base.OnConfiguring(optionsBuilder);
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
@ -19,5 +19,7 @@ namespace MotorPlantDatabaseImplement
public virtual DbSet<Engine> Engines { get; set; }
public virtual DbSet<EngineComponent> EngineComponents { get; set; }
public virtual DbSet<Order> Orders { get; set; }
}
public virtual DbSet<Shop> Shops { get; set; }
public virtual DbSet<ShopEngine> ShopEngines { get; set; }
}
}

View File

@ -21,8 +21,4 @@
<ProjectReference Include="..\MotorPlantDataModels\MotorPlantDataModels.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Implements\" />
</ItemGroup>
</Project>

View File

@ -84,7 +84,7 @@ namespace MotorPlantView.Forms
var operationResult = _logicO.CreateOrder(new OrderBindingModel
{
EngineId = Convert.ToInt32(comboBoxEngine.SelectedValue),
Count = Convert.ToInt32(textBoxCount.Text),
Count = Convert.ToInt32(textBoxCount.Text),
Sum = Convert.ToDouble(textBoxSum.Text)
});
if (!operationResult)
@ -97,7 +97,8 @@ namespace MotorPlantView.Forms
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка создания заказа"); MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
_logger.LogError(ex, "Ошибка создания заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

View File

@ -30,7 +30,7 @@ namespace MotorPlantView.Forms
{
dataGridView.DataSource = list;
dataGridView.Columns["EngineId"].Visible = false;
dataGridView.Columns["EngineName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
dataGridView.Columns["EngineName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}
_logger.LogInformation("Загрузка заказов");