Lab3 Hard

This commit is contained in:
Павел Сорокин 2023-03-19 17:23:42 +04:00
parent 572b93667a
commit 573ec0bb49
9 changed files with 706 additions and 4 deletions

View File

@ -81,7 +81,7 @@ namespace ShipyardDataBaseImplement.Implements
}
product.Update(model);
context.SaveChanges();
product.UpdateComponents(context, model);
product.UpdateDetails(context, model);
transaction.Commit();
return product.GetViewModel;
}

View File

@ -0,0 +1,158 @@
using Microsoft.EntityFrameworkCore;
using ShipyardContracts.BindingModels;
using ShipyardContracts.SearchModels;
using ShipyardContracts.StoragesContracts;
using ShipyardContracts.ViewModels;
using ShipyardDataBaseImplement.Models;
using ShipyardDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Runtime.ConstrainedExecution;
using System.Text;
using System.Threading.Tasks;
namespace ShipyardDataBaseImplement.Implements
{
public class ShopStorage : IShopStorage
{
public ShopViewModel? GetElement(ShopSearchModel model)
{
if (string.IsNullOrEmpty(model.ShopName) &&
!model.Id.HasValue)
{
return null;
}
using var context = new ShipyardDataBase();
return context.Shops
.Include(x => x.Ships)
.ThenInclude(x => x.Ship)
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.ShopName) &&
x.ShopName == model.ShopName) ||
(model.Id.HasValue && x.Id ==
model.Id))
?.GetViewModel;
}
public List<ShopViewModel> GetFilteredList(ShopSearchModel model)
{
if (string.IsNullOrEmpty(model.ShopName))
{
return new();
}
using var context = new ShipyardDataBase();
return context.Shops
.Include(x => x.Ships)
.ThenInclude(x => x.Ship)
.Where(x => x.ShopName.Contains(model.ShopName))
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
public List<ShopViewModel> GetFullList()
{
using var context = new ShipyardDataBase();
return context.Shops.Include(x => x.Ships)
.ThenInclude(x => x.Ship)
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
public ShopViewModel? Insert(ShopBindingModel model)
{
using var context = new ShipyardDataBase();
var newProduct = Shop.Create(context, model);
if (newProduct == null)
{
return null;
}
context.Shops.Add(newProduct);
context.SaveChanges();
return newProduct.GetViewModel;
}
public ShopViewModel? Update(ShopBindingModel model)
{
using var context = new ShipyardDataBase();
using var transaction = context.Database.BeginTransaction();
try
{
var shop = context.Shops.FirstOrDefault(rec =>
rec.Id == model.Id);
if (shop == null)
{
return null;
}
shop.Update(model);
context.SaveChanges();
shop.UpdateShips(context, model);
transaction.Commit();
return shop.GetViewModel;
}
catch
{
transaction.Rollback();
throw;
}
}
public ShopViewModel? Delete(ShopBindingModel model)
{
using var context = new ShipyardDataBase();
var element = context.Shops
.Include(x => x.Ships)
.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Shops.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
public bool SellShips(IShipModel model, int count)
{
using var context = new ShipyardDataBase();
using var transaction = context.Database.BeginTransaction();
try
{
List<Shop> shopsWithShip = context.Shops.Include(x => x.Ships).ThenInclude(x => x.Ship).Where(x => x.Ships.Any(x => x.ShipId == model.Id)).ToList();
foreach (var shop in shopsWithShip)
{
int carInShopCount = shop.ShopShips[model.Id].Item2;
if (count - carInShopCount >= 0)
{
count -= carInShopCount;
context.ShopShips.Remove(shop.Ships.FirstOrDefault(x => x.ShipId == model.Id)!);
shop.ShopShips.Remove(model.Id);
}
else
{
shop.ShopShips[model.Id] = (model, carInShopCount - count);
count = 0;
shop.UpdateShips(context, new()
{
Id = shop.Id,
ShopShips = shop.ShopShips
});
}
if (count == 0)
{
context.SaveChanges();
transaction.Commit();
return true;
}
}
transaction.Rollback();
return false;
}
catch
{
transaction.Rollback();
throw;
}
}
}
}

View File

@ -0,0 +1,250 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using ShipyardDataBaseImplement;
#nullable disable
namespace ShipyardDataBaseImplement.Migrations
{
[DbContext(typeof(ShipyardDataBase))]
[Migration("20230319132059_ShopMigration")]
partial class ShopMigration
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Detail", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<double>("Cost")
.HasColumnType("float");
b.Property<string>("DetailName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Details");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int>("ShipId")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("ShipId");
b.ToTable("Orders");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Ship", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<double>("Price")
.HasColumnType("float");
b.Property<string>("ShipName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Ships");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.ShipDetail", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("DetailId")
.HasColumnType("int");
b.Property<int>("ShipId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("DetailId");
b.HasIndex("ShipId");
b.ToTable("ShipDetails");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Shop", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Address")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("Capacity")
.HasColumnType("int");
b.Property<DateTime>("DateOpen")
.HasColumnType("datetime2");
b.Property<string>("ShopName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Shops");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.ShopShip", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("ShipId")
.HasColumnType("int");
b.Property<int>("ShopId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("ShipId");
b.HasIndex("ShopId");
b.ToTable("ShopShips");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Order", b =>
{
b.HasOne("ShipyardDataBaseImplement.Models.Ship", "Ship")
.WithMany("Orders")
.HasForeignKey("ShipId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ship");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.ShipDetail", b =>
{
b.HasOne("ShipyardDataBaseImplement.Models.Detail", "Detail")
.WithMany("ShipDetails")
.HasForeignKey("DetailId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ShipyardDataBaseImplement.Models.Ship", "Ship")
.WithMany("Details")
.HasForeignKey("ShipId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Detail");
b.Navigation("Ship");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.ShopShip", b =>
{
b.HasOne("ShipyardDataBaseImplement.Models.Ship", "Ship")
.WithMany("Ships")
.HasForeignKey("ShipId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ShipyardDataBaseImplement.Models.Shop", "Shop")
.WithMany("Ships")
.HasForeignKey("ShopId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ship");
b.Navigation("Shop");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Detail", b =>
{
b.Navigation("ShipDetails");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Ship", b =>
{
b.Navigation("Details");
b.Navigation("Orders");
b.Navigation("Ships");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Shop", b =>
{
b.Navigation("Ships");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,78 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ShipyardDataBaseImplement.Migrations
{
/// <inheritdoc />
public partial class ShopMigration : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Shops",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ShopName = table.Column<string>(type: "nvarchar(max)", nullable: false),
Address = table.Column<string>(type: "nvarchar(max)", nullable: false),
DateOpen = table.Column<DateTime>(type: "datetime2", nullable: false),
Capacity = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Shops", x => x.Id);
});
migrationBuilder.CreateTable(
name: "ShopShips",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ShopId = table.Column<int>(type: "int", nullable: false),
ShipId = table.Column<int>(type: "int", nullable: false),
Count = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ShopShips", x => x.Id);
table.ForeignKey(
name: "FK_ShopShips_Ships_ShipId",
column: x => x.ShipId,
principalTable: "Ships",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ShopShips_Shops_ShopId",
column: x => x.ShopId,
principalTable: "Shops",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_ShopShips_ShipId",
table: "ShopShips",
column: "ShipId");
migrationBuilder.CreateIndex(
name: "IX_ShopShips_ShopId",
table: "ShopShips",
column: "ShopId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "ShopShips");
migrationBuilder.DropTable(
name: "Shops");
}
}
}

View File

@ -121,6 +121,59 @@ namespace ShipyardDataBaseImplement.Migrations
b.ToTable("ShipDetails");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Shop", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Address")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("Capacity")
.HasColumnType("int");
b.Property<DateTime>("DateOpen")
.HasColumnType("datetime2");
b.Property<string>("ShopName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Shops");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.ShopShip", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("ShipId")
.HasColumnType("int");
b.Property<int>("ShopId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("ShipId");
b.HasIndex("ShopId");
b.ToTable("ShopShips");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Order", b =>
{
b.HasOne("ShipyardDataBaseImplement.Models.Ship", "Ship")
@ -151,6 +204,25 @@ namespace ShipyardDataBaseImplement.Migrations
b.Navigation("Ship");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.ShopShip", b =>
{
b.HasOne("ShipyardDataBaseImplement.Models.Ship", "Ship")
.WithMany("Ships")
.HasForeignKey("ShipId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ShipyardDataBaseImplement.Models.Shop", "Shop")
.WithMany("Ships")
.HasForeignKey("ShopId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ship");
b.Navigation("Shop");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Detail", b =>
{
b.Navigation("ShipDetails");
@ -161,6 +233,13 @@ namespace ShipyardDataBaseImplement.Migrations
b.Navigation("Details");
b.Navigation("Orders");
b.Navigation("Ships");
});
modelBuilder.Entity("ShipyardDataBaseImplement.Models.Shop", b =>
{
b.Navigation("Ships");
});
#pragma warning restore 612, 618
}

View File

@ -36,6 +36,8 @@ namespace ShipyardDataBaseImplement.Models
public virtual List<ShipDetail> Details { get; set; } = new();
[ForeignKey("ShipId")]
public virtual List<Order> Orders { get; set; } = new();
[ForeignKey("ShipId")]
public virtual List<ShopShip> Ships { get; set; } = new();
public static Ship Create(ShipyardDataBase context, ShipBindingModel model)
{
return new Ship()
@ -63,17 +65,16 @@ namespace ShipyardDataBaseImplement.Models
Price = Price,
ShipDetails = ShipDetails
};
public void UpdateComponents(ShipyardDataBase context,
public void UpdateDetails(ShipyardDataBase context,
ShipBindingModel model)
{
var shipDetails = context.ShipDetails.Where(rec =>
rec.ShipId == model.Id).ToList();
if (shipDetails != null && shipDetails.Count > 0)
{ // удалили те, которых нет в модели
{
context.ShipDetails.RemoveRange(shipDetails.Where(rec
=> !model.ShipDetails.ContainsKey(rec.DetailId)));
context.SaveChanges();
// обновили количество у существующих записей
foreach (var updateDetail in shipDetails)
{
updateDetail.Count = model.ShipDetails[updateDetail.DetailId].Item2;

View File

@ -0,0 +1,106 @@
using ShipyardContracts.BindingModels;
using ShipyardContracts.ViewModels;
using ShipyardDataModels.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 ShipyardDataBaseImplement.Models
{
public class Shop : IShopModel
{
public int Id { get; set; }
[Required]
public string ShopName { get; set; } = string.Empty;
[Required]
public string Address { get; set; } = string.Empty;
[Required]
public DateTime DateOpen { get; set; }
[Required]
public int Capacity { get; set; }
private Dictionary<int, (IShipModel, int)>? _shopShips = null;
[NotMapped]
public Dictionary<int, (IShipModel, int)> ShopShips
{
get
{
if (_shopShips == null)
{
_shopShips = Ships
.ToDictionary(recST => recST.ShipId, recST => (recST.Ship as IShipModel, recST.Count));
}
return _shopShips;
}
}
[ForeignKey("ShopId")]
public virtual List<ShopShip> Ships { get; set; } = new();
public static Shop Create(ShipyardDataBase context, ShopBindingModel model)
{
return new Shop()
{
Id = model.Id,
ShopName = model.ShopName,
Address = model.Address,
DateOpen = model.DateOpen,
Capacity = model.Capacity,
Ships = model.ShopShips.Select(x => new ShopShip
{
Ship = context.Ships.First(y => y.Id == x.Key),
Count = x.Value.Item2
}).ToList()
};
}
public void Update(ShopBindingModel model)
{
ShopName = model.ShopName;
Address = model.Address;
DateOpen = model.DateOpen;
Capacity = model.Capacity;
}
public ShopViewModel GetViewModel => new()
{
Id = Id,
ShopName = ShopName,
Address = Address,
DateOpen = DateOpen,
Capacity = Capacity,
ShopShips = ShopShips
};
public void UpdateShips(ShipyardDataBase context, ShopBindingModel model)
{
var shopShips = context.ShopShips.Where(rec => rec.ShipId == model.Id).ToList();
if (shopShips != null && shopShips.Count > 0)
{
context.ShopShips.RemoveRange(shopShips.Where(rec => !model.ShopShips.ContainsKey(rec.ShipId)));
context.SaveChanges();
foreach (var updateShip in shopShips)
{
updateShip.Count = model.ShopShips[updateShip.ShipId].Item2;
model.ShopShips.Remove(updateShip.ShipId);
}
context.SaveChanges();
}
var shop = context.Shops.First(x => x.Id == Id);
foreach (var id in model.ShopShips)
{
context.ShopShips.Add(new ShopShip
{
Shop = shop,
Ship = context.Ships.First(x => x.Id == id.Key),
Count = id.Value.Item2
});
context.SaveChanges();
}
_shopShips = null;
}
}
}

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ShipyardDataBaseImplement.Models
{
public class ShopShip
{
public int Id { get; set; }
[Required]
public int ShopId { get; set; }
[Required]
public int ShipId { get; set; }
[Required]
public int Count { get; set; }
public virtual Ship Ship { get; set; } = new();
public virtual Shop Shop { get; set; } = new();
}
}

View File

@ -23,6 +23,8 @@ namespace ShipyardDataBaseImplement
public virtual DbSet<Ship> Ships { set; get; }
public virtual DbSet<ShipDetail> ShipDetails { set; get; }
public virtual DbSet<Order> Orders { set; get; }
public virtual DbSet<Shop> Shops { set; get; }
public virtual DbSet<ShopShip> ShopShips { set; get; }
}
}