Отключить удаление для записей с зависимостями - PullRequest
0 голосов
/ 08 октября 2019

Я хочу удалить записи из моей базы данных, которые не имеют никаких зависимостей.

например, : - 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);
        }
    }
}

1 Ответ

1 голос
/ 09 октября 2019

Если у вас есть свойства навигации в вашей сущности, тогда вы можете просто проверить, не равны ли их ключи нулю:

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();
...