c# - 禁用删除具有依赖关系的记录
问题描述
我只想从我的数据库中删除没有任何依赖关系的记录。
例如:-Company
表有Company Pk
主键,它是department
表和location
表的外键。因此,如果公司与和company
有依赖关系,则系统不应允许用户从中删除公司。department
location
可以删除没有任何依赖关系的记录。我该怎么做?
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Threading.Tasks;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Payroll.Core.Domain;
using Payroll.Infrastructure.Data;
using AutoMapper;
using Payroll.Web.Dto;
using Payroll.Core.Interfaces;
using Payroll.Infrastructure.Validators;
namespace Payroll.Web.Controllers
{
[RoutePrefix("Company")]
public class CompanyController : Controller
{
private readonly IMapper _mapper = null;
private readonly IUnitOfWork _work = null;
public CompanyController(IUnitOfWork work, IMapper mapper)
{
_work = work;
_mapper = mapper;
}
// GET: Company
public async Task<ActionResult> Index()
{
var companies = await _work.Companies.GetAllAsync();
var companyDtos = _mapper.Map<List<CompanyDto>>(companies);
return View(companyDtos);
}
// GET: Company/5
[Route("{companyPk:int}")]
public async Task<ActionResult> Details(int? companyPk)
{
//Validate parameters
if (companyPk == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Company identifier is missing.");
}
//Get model from db
Company company = await _work.Companies.GetAsync(companyPk);
if (company == null)
{
return HttpNotFound();
}
//Convert model to dto
CompanyDto companyDto = _mapper.Map<CompanyDto>(company);
return View(companyDto);
}
// GET: Company/New
[Route("New")]
public ActionResult New()
{
var dto = new CompanyDto();
return View(dto);
}
// POST: Company/New
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
[Route("New")]
public async Task<ActionResult> New(CompanyDto companyDto)
{
//Validate Dto state
if (ModelState.IsValid)
{
//Convert dto to model
Company company = _mapper.Map<Company>(companyDto);
//Assign model properties
company.CompanyPk = new Random().Next(1, 10);
Utilities.Instance.SetEntityProperties(company);
//Validate model
var validator = new CompanyValidator();
var validation = await validator.ValidateAsync(company);
if (validation.IsValid)
{
//Save model to db
_work.Companies.Add(company);
await _work.CompleteAsync();
return RedirectToAction("Index");
}
else
{
foreach (var error in validation.Errors)
{
ModelState.AddModelError(error.PropertyName, error.ErrorMessage);
}
}
}
return View(companyDto);
}
// GET: Company/5/Edit
[Route("{companyPk:int}/Edit")]
public async Task<ActionResult> Edit(int? companyPk)
{
//Validate parameters
if (companyPk == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Company identifier is missing.");
}
//Get the model from db
Company company = await _work.Companies.GetAsync(companyPk);
if (company == null)
{
return HttpNotFound();
}
//Convert model to dto
CompanyDto companyDto = _mapper.Map<CompanyDto>(company);
return View(companyDto);
}
// POST: Company/5/Edit
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
[Route("{companyPk:int}/Edit")]
public async Task<ActionResult> Edit(int? companyPk, CompanyDto companyDto)
{
//Validate parameters
if (companyPk == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Company identifier is missing.");
}
//Validate Dto state
if (ModelState.IsValid)
{
//Get the model from db
//Because the record now being edited can be changed by another process
var company = await _work.Companies.GetAsync(companyPk);
if (company == null)
{
return HttpNotFound();
}
//Map the previous state of the model to log
var logCompany = _mapper.Map<LogCompany>(company);
//Convert dto to model
//This is a specific mapping which modifies the original model from only bound properties of Dto
_mapper.Map(companyDto, company);
//Validate model
var validator = new CompanyValidator();
var validation = await validator.ValidateAsync(company);
if (validation.IsValid)
{
//Assign log model properties
logCompany.RecordId = 0;
Utilities.Instance.SetLogEntityProperties(logCompany, "E");
//Save model to db
_work.LogCompanies.Add(logCompany);
_work.Companies.Update(company);
await _work.CompleteAsync();
return RedirectToAction("Index");
}
else
{
foreach (var error in validation.Errors)
{
ModelState.AddModelError(error.PropertyName, error.ErrorMessage);
}
}
}
return View(companyDto);
}
// GET: Company/5/Delete
[Route("{companyPk:int}/Delete")]
public async Task<ActionResult> Delete(int? companyPk)
{
//Validate parameters
if (companyPk == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Company identifier is missing.");
}
//Get the model from db
Company company = await _work.Companies.GetAsync(companyPk);
if (company == null)
{
return HttpNotFound();
}
//Convert model to dto
CompanyDto companyDto = _mapper.Map<CompanyDto>(company);
return View(companyDto);
}
// POST: Company/5/Delete
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
[Route("{companyPk:int}/Delete")]
public async Task<ActionResult> DeleteConfirmed(int companyPk)
{
//Get the model from db
Company company = await _work.Companies.GetAsync(companyPk);
//Prepare log model
var logCompany = _mapper.Map<LogCompany>(company);
logCompany.RecordId = 0;
Utilities.Instance.SetLogEntityProperties(logCompany, "D");
//Save model to db
_work.LogCompanies.Add(logCompany);
_work.Companies.Remove(company);
await _work.CompleteAsync();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_work.Dispose();
}
base.Dispose(disposing);
}
}
}
解决方案
如果您的实体中有导航属性,那么您可以检查它们的键是否不为空:
company.LocationId !=null && company.DepartmentId!=null
如果您没有 Id 属性(EF 可以按照惯例创建它们),请阅读此文档并加载实体。假设这不会增加太多开销。
var company = _work.Companies.Where(b => b.CompanyPk == companyPk)
.Include(b => b.Location)
.Include(b => b.Department)
.FirstOrDefault();
company.Location !=null && company.Department!=null
希望这不是生产代码:
company.CompanyPk = new Random().Next(1, 10);
并且永远不会破坏注入的依赖项。这是一个危险信号,因为您无法控制它的生命周期,如果有池怎么办?规则是 - 你没有创造它,你没有责任摧毁它。如果您想明确控制生命周期 - 然后注入工厂,创建服务,使用和销毁。
_work.Dispose();
推荐阅读
- flutter - Cubit 和 Bloc 有什么区别?
- python-3.x - 如何通过 GMT 小时而不是位置字符串使 datetime 对象时区感知
- python - 如何仅根据python中的索引更新列表中的列表,而不更新所有列表
- flutter - VmService时间戳与flutter驱动时间线事件时间戳不对应
- python - Timeit 模块,三引号代码与函数
- angular - GrapesJS not displayed properly
- java - 转换地图
> 到嵌套 JSON - javascript - 找出一串数字中的最大小数位数
- c# - 如何从 Angular 请求 c# 控制器中的参数?(没有 url 连接)
- html - css:图像在垂直居中时覆盖容器