2017-09-26 15 views
1

私はASP.NET Core MVCを初めて使用しています。私はASP.NET Core 2.0、C#、EntityFrameworkCoreコードファースト、SQL Server 2016を使用しています。私はCRUDオペレーションを必要に応じて動作させることができました。ASP.NET Core 2.0重複したエントリを防ぐ

ただし、ユーザーが自分のフォームに複数回登録できないようにするための助けが必要です。可能であれば、データベース内ではなくコントローラ側のコード内から重複したエントリをチェック/防止したいと思います。

誰かが助けることができるなら、私が今持っているコードを添付します。前もって感謝します!

モデル

public class Employee 
{ 
    public int EmployeeID { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    public int DepartmentID { get; set; } 
    public Department Department { get; set; } 

    public int AppointmentID { get; set; } 
    public Appointment Appointment { get; set; } 
} 

public class Department 
{ 
    public int DepartmentID { get; set; } 
    public string Name { get; set; } 

    public ICollection<Employee> Employees { get; set; } 
} 

public class Appointment 
{ 
    public int AppointmentID { get; set; } 
    public string TimeSlot { get; set; } 

    public ICollection<Employee> Employees { get; set; } 
} 

のviewmodels

public class EmployeeFormVM 
{ 
    public int EmployeeID { get; set; } 

    [Required(ErrorMessage = "Please enter your First Name")] 
    [Display(Name = "First Name")] 
    [StringLength(50)] 
    public string FirstName { get; set; } 

    [Required(ErrorMessage = "Please enter your Last Name")] 
    [Display(Name = "Last Name")] 
    [StringLength(50)] 
    public string LastName { get; set; } 

    [Required(ErrorMessage = "Please select your Department")] 
    [Display(Name = "Department")] 
    public int DepartmentID { get; set; } 

    public IEnumerable<Department> Departments { get; set; } 

    [Required(ErrorMessage = "Please select your Appointment")] 
    [Display(Name = "Appointment")] 
    public int AppointmentID { get; set; } 

    public IEnumerable<Appointment> Appointments { get; set; } 
} 

DbContext

public class WinTenDbContext : DbContext 
{ 
    public WinTenDbContext(DbContextOptions<WinTenDbContext> options) : base(options) 
    { 
    } 

    public DbSet<Employee> Employees { get; set; } 
    public DbSet<Department> Departments { get; set; } 
    public DbSet<Appointment> Appointments { get; set; } 

    protected override void OnModelCreating(ModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Employee>() 
      .HasKey(e => e.EmployeeID); 

     modelBuilder.Entity<Employee>() 
      .Property(e => e.FirstName) 
      .HasColumnType("varchar(50)") 
      .HasMaxLength(50) 
      .IsRequired(); 


     modelBuilder.Entity<Employee>() 
      .Property(e => e.LastName) 
      .HasColumnType("varchar(50)") 
      .HasMaxLength(50) 
      .IsRequired();    

     modelBuilder.Entity<Department>() 
      .HasKey(d => d.DepartmentID); 

     modelBuilder.Entity<Department>() 
      .Property(d => d.Name) 
      .HasColumnType("varchar(50)") 
      .HasMaxLength(50); 

     modelBuilder.Entity<Appointment>() 
      .HasKey(a => a.AppointmentID); 

     modelBuilder.Entity<Appointment>() 
      .Property(a => a.TimeSlot) 
      .HasColumnType("varchar(50)") 
      .HasMaxLength(50); 
    } 
} 

EmployeesController

public class EmployeesController : Controller 
{ 
    private readonly WinTenDbContext _context; 

    public EmployeesController(WinTenDbContext context) 
    { 
     _context = context; 
    } 

    // GET: Employees 
    public async Task<IActionResult> Index() 
    { 
     //return View(await _context.Employees.ToListAsync()); 

     var webAppDbContext = _context.Employees.Include(d => d.Department).Include(a => a.Appointment); 
     return View(await webAppDbContext.ToListAsync()); 
    } 

    // GET: Employees/Details/5 
    public async Task<IActionResult> Details(int? id) 
    { 
     if (id == null) 
     { 
      return NotFound(); 
     } 

     var employee = await _context.Employees 
      .SingleOrDefaultAsync(m => m.EmployeeID == id); 
     if (employee == null) 
     { 
      return NotFound(); 
     } 

     return View(employee); 
    } 

    // GET: Employees/Create 
    public IActionResult Create() 
    { 
     var departments = _context.Departments.ToList(); 
     var appointments = _context.Appointments.ToList(); 

     var viewModel = new EmployeeFormVM 
     { 
      Departments = departments, 
      Appointments = appointments 
     }; 

     return View(viewModel); 
    } 

    // POST: Employees/Create 
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see http://go.microsoft.com/fwlink/?LinkId=317598. 
    [HttpPost] 
    [ValidateAntiForgeryToken] 
    public async Task<IActionResult> Create(EmployeeFormVM employee) 
    { 
     if (ModelState.IsValid) 
     { 
      var emp = new Employee(); 
      { 
       emp.FirstName = employee.FirstName; 
       emp.LastName = employee.LastName; 
       emp.DepartmentID = employee.DepartmentID; 
       emp.AppointmentID = employee.AppointmentID; 
      } 
      _context.Add(emp); 
      await _context.SaveChangesAsync(); 
      return RedirectToAction(nameof(Index)); 
     } 

     else 
     { 
      employee.Departments = _context.Departments.ToList(); 
      employee.Appointments = _context.Appointments.ToList(); 
      return View(employee); 
     } 
    } 

    // GET: Employees/Edit/5 
    public async Task<IActionResult> Edit(int? id) 
    { 
     if (id == null) 
     { 
      return NotFound(); 
     } 

     var employeevm = new EmployeeFormVM(); 
     { 
      Employee employee = await _context.Employees.SingleOrDefaultAsync(m => m.EmployeeID == id); 

      if (employee == null) 
      { 
       return NotFound(); 
      } 

      employeevm.EmployeeID = employee.EmployeeID; 
      employeevm.FirstName = employee.FirstName; 
      employeevm.LastName = employee.LastName; 

      // Retrieve list of Departments 
      var departments = _context.Departments.ToList(); 
      employeevm.Departments = departments; 
      // Set the selected department 
      employeevm.DepartmentID = employee.DepartmentID; 

      // Retrieve list of Appointments 
      var appointments = _context.Appointments.ToList(); 
      employeevm.Appointments = appointments; 
      // Set the selected department 
      employeevm.AppointmentID = employee.AppointmentID; 
     } 
     return View(employeevm); 
    } 

    // POST: Employees/Edit/5 
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see http://go.microsoft.com/fwlink/?LinkId=317598. 
    [HttpPost] 
    [ValidateAntiForgeryToken] 
    public async Task<IActionResult> Edit(EmployeeFormVM vmEdit) 
    { 
     if (ModelState.IsValid) 
     { 
      Employee employee = _context.Employees.SingleOrDefault(e => e.EmployeeID == vmEdit.EmployeeID); 

      if (employee == null) 
      { 
       return NotFound(); 
      } 

      employee.FirstName = vmEdit.FirstName; 
      employee.LastName = vmEdit.LastName; 
      employee.DepartmentID = vmEdit.DepartmentID; 
      employee.AppointmentID = vmEdit.AppointmentID; 

      try 
      { 
       _context.Update(employee); 
       await _context.SaveChangesAsync(); 
      } 
      catch (DbUpdateConcurrencyException) 
      { 
       if (!EmployeeExists(vmEdit.EmployeeID)) 
       { 
        return NotFound(); 
       } 
       else 
       { 
        throw; 
       } 
      } 
      return RedirectToAction(nameof(Index)); 
     } 
     return View(vmEdit); 
    } 

    // GET: Employees/Delete/5 
    public async Task<IActionResult> Delete(int? id) 
    { 
     if (id == null) 
     { 
      return NotFound(); 
     } 

     var employee = await _context.Employees 
      .SingleOrDefaultAsync(m => m.EmployeeID == id); 
     if (employee == null) 
     { 
      return NotFound(); 
     } 

     return View(employee); 
    } 

    // POST: Employees/Delete/5 
    [HttpPost, ActionName("Delete")] 
    [ValidateAntiForgeryToken] 
    public async Task<IActionResult> DeleteConfirmed(int id) 
    { 
     var employee = await _context.Employees.SingleOrDefaultAsync(m => m.EmployeeID == id); 
     _context.Employees.Remove(employee); 
     await _context.SaveChangesAsync(); 
     return RedirectToAction(nameof(Index)); 
    } 

    private bool EmployeeExists(int id) 
    { 
     return _context.Employees.Any(e => e.EmployeeID == id); 
    } 
} 

ビュー作成

@using (Html.BeginForm("Create", "Employees")) 
    { 
     <div class="form-group"> 
      @Html.LabelFor(e => e.FirstName) 
      @Html.TextBoxFor(e => e.FirstName, new { @class = "form-control" }) 
      @Html.ValidationMessageFor(e => e.FirstName) 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(e => e.LastName) 
      @Html.TextBoxFor(e => e.LastName, new { @class = "form-control" }) 
      @Html.ValidationMessageFor(e => e.LastName) 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(d => d.DepartmentID) 
      @Html.DropDownListFor(d => d.DepartmentID, new SelectList(Model.Departments, "DepartmentID", "Name"), "", new { @class = "form-control" }) 
      @Html.ValidationMessageFor(d => d.DepartmentID) 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(a => a.AppointmentID) 
      @Html.DropDownListFor(a => a.AppointmentID, new SelectList(Model.Appointments, "AppointmentID", "TimeSlot"), "", new { @class = "form-control" }) 
      @Html.ValidationMessageFor(a => a.AppointmentID) 
     </div> 

     <div class="form-group"> 
      <button type="submit" class="btn btn-primary">Submit</button> 
     </div> 
    } 

答えて

3

あなたは確かにコード側からの重複したエントリをチェックすることができますが、もちろん実現するために、データベースに対してクエリを実行する必要がありますこの。あなたの投稿コードから、あなたはすでにEmployeesController.Editに似たような操作を行います。

Employee employee = await _context.Employees.SingleOrDefaultAsync(
    m => m.EmployeeID == id); 

if (employee == null) 
{ 
    return NotFound(); 
} 

あなたがこのアプローチを取るとEmployeesController.Createに変化を適用することができます。例えば:

Employee existingEmployee = await _context.Employees.SingleOrDefaultAsync(
    m => m.FirstName == employee.FirstName && m.LastName == employee.LastName); 

if (existingEmployee != null) 
{ 
    // The employee already exists. 
    // Do whatever you need to do - This is just an example. 
    ModelState.AddModelError(string.Empty, "This employee already exists."); 
    employee.Departments = _context.Departments.ToList(); 
    employee.Appointments = _context.Appointments.ToList(); 
    return View(employee); 
} 

// Your existing code for creating a new employee. 

私はSingleOrDefaultAsyncに使用してきた表現は一例です:あなたは、独自の要件に応じて従業員のユニークなものを決定する必要があります。コントローラのコードで追加のエラーメッセージを表示するには

私が示されてきた、あなたはビューを作成、更新する必要があります:

@using (Html.BeginForm("Create", "Employees")) 
{ 
    @Html.ValidationSummary(true) 
    ... 
+0

バック返信いただきありがとうございます。元の投稿されたコードの中であなたが提供したものを実装する必要がありますか? ** [HttpPost] **(ModelState.IsValid)**コードを作成しますが、姓と名字を重複して入力しようとすると、このエラーが発生します** ArgumentNullException:値をnullにすることはできません。 パラメータ名:この行のコード** @Html.DropDownListFor(d => d.DepartmentID、new SelectList(Model.Departments、 "DepartmentID"、 "Name")、 ""、new {@class = "form-control"})** – Brian

+0

あなたの特定の問題に対処するための答えを編集しました。あなたは、これが追加する複製を削除するために関数の再構成を検討したいと思うでしょうが、私はここであなたの特定の質問の範囲外だと思います。 –

+0

ありがとうございました。ただし、**この従業員は既に存在しています。**というエラーメッセージは表示されませんでした。**重複したエントリを入力しようとしたときに、作成ビューに追加する必要がありますか?また、私があなたが言及した機能を再構成しなければならない理由もあります。 – Brian

関連する問題