/ / Jaki jest najlepszy sposób obsługi wstawiania / aktualizowania obiektu z polami wyboru wielu kategorii? - sql, asp.net-mvc

Jaki jest najlepszy sposób obsługi wstawiania / aktualizowania obiektu z polami wyboru wielu kategorii? - sql, asp.net-mvc

Potrzebuję wskazówek dotyczących najlepszych praktyk.

Mam dwie tabele SQL, jedną o nazwie Osoba, którazawiera PersonId, PersonName i inną o nazwie Category, która zawiera CategoryId, CategoryName. Kategorie mogą być dość liczne i od czasu do czasu dodawane.

Chcę utworzyć widok, który pokazuje pole tekstowe PersonName, a następnie pojedyncze pole wyboru dla każdej kategorii w tabeli kategorii.

Użytkownik może wprowadzić nazwę i zaznaczyć tyle pól wyboru kategorii, ile chce, a następnie zapisać.

To poprawne podejście do wstawiania PersonNamew tabeli Person, a następnie wstaw wpis dla każdej kombinacji osoby / kategorii w nowej tabeli o nazwie PersonCategory, która zawiera pola PersonId i CategoryId?

Jeśli to zrobię, jak obsługiwać aktualizacje, jeśli kategorie zostaną zmienione w widoku edycji? To kategoria może być odznaczona przeciwko osobie. Czy rekord w PersonCategory wymaga usunięcia?

Odpowiedzi:

1 dla odpowiedzi № 1

Tak to robię. Przejdę przez następujące.

  1. Wyświetl model
  2. Widok ASP.NET MVC (interfejs użytkownika)
  3. Metoda kontroli po akcji
  4. Algorytm do zapisania

Wyświetl model

public class PersonViewModel
{
public int Id { get; set; }

public string PersonName { get; set; }

// For rendering Checkboxes in the MVC View
public IList<SelectListItem> CategoryCheckboxes { get; set; }

// For data binding on Postback (HTTP POST).
// <input type="checkbox" /> will have the same `name` attribute as this.
public IList<int> AssociatedCategories { get; set; }
}

Widok ASP.NET MVC

<div>Name: <%= Html.EditorFor( m => m.PersonName ) %></div>

<fieldset>
<legend>Associatied Categories</legend>

<% foreach (SelectListItem c in Model.CategoryCheckboxes) { %>
<!-- "name" attribute is same as the C# View Model property name -->
<%= Html.CheckBox( "AssociatedCategories", c.Selected, new Dictionary<string, object> { { "value", c.Value } } ); %>
<%= Html.Encode( c.Text ) %><br />
<% } %>

</fieldset>

Metoda post akcji kontrolera

[HttpPost]
public ActionResult Edit(PersonViewModel viewModel)
{
Person p = personService.Update( viewModel ); // persist changes to DB
if (p == null) // person record doesn"t exist in DB
return RedirectToAction("NotFound");

return RedirectToAction("Edit", new { id = viewModel.Id });
}

Algorytm do zapisania

// this is in the `PersonService` class.
public void Update(PersonViewModel viewModel)
{
Person p = personRepository.GetByPrimaryKey( viewModel.Id );
if (p == null)
return null;

p.PersonName = viewModel.PersonName;


IList<int> existingAssociatedCategories = GetAssociatedCategories( p.PersonId );
foreach( int i in viewModel.AssociatedCategories )
{
if (!existingAssociatedCategories.Contains( i ))
Associate( p.PersonId, i ); // add NEW association in DB
}


foreach( int k in  existingAssociatedCategories)
{
if (!viewModel.AssociatedCategories.Contains( k ))
DeleteAssociation( p.PersonId, k ); // delete existing association
}

repository.UpdatePerson( p ); // save changes to DB for Person object

return p;
}



Daj mi znać, jeśli masz jakieś pytanie.


3 dla odpowiedzi № 2

Zazwyczaj w przypadku czegoś takiego powstrzymałbym się od aktualizacji. Chciałbym usunąć wszystkie wpisy dla danej osoby z PersonCategory, a następnie ponownie wstaw te, które są zapisywane PersonCategory.


1 dla odpowiedzi nr 3

Odpowiedzi na twoje pytania brzmią: tak, dodaj / usuń je tam, gdzie dodano / usunięto, i tak.

Jest to relacja wiele do wielu, która jest reprezentowana relacyjnie za pomocą tabeli łączy.


1 dla odpowiedzi nr 4

Tak to robię. Przejdę przez następujące.

  1. Wyświetl model
  2. Widok ASP.NET MVC (interfejs użytkownika)
  3. Metoda kontroli po akcji
  4. Algorytm do zapisania

Wyświetl model

public class PersonViewModel
{
public int Id { get; set; }

public string PersonName { get; set; }

// For rendering Checkboxes in the MVC View
public IList<SelectListItem> CategoryCheckboxes { get; set; }

// For data binding on Postback (HTTP POST).
// <input type="checkbox" /> will have the same `name` attribute as this.
public IList<int> AssociatedCategories { get; set; }
}

Widok ASP.NET MVC

<div>Name: <%= Html.EditorFor( m => m.PersonName ) %></div>

<fieldset>
<legend>Associatied Categories</legend>

<% foreach (SelectListItem c in Model.CategoryCheckboxes) { %>
<!-- "name" attribute is same as the C# View Model property name -->
<%= Html.CheckBox( "AssociatedCategories", c.Selected, new Dictionary<string, object> { { "value", c.Value } } ); %>
<%= Html.Encode( c.Text ) %><br />
<% } %>

</fieldset>

Metoda post akcji kontrolera

[HttpPost]
public ActionResult Edit(PersonViewModel viewModel)
{
Person p = personService.Update( viewModel ); // persist changes to DB
if (p == null) // person record doesn"t exist in DB
return RedirectToAction("NotFound");

return RedirectToAction("Edit", new { id = viewModel.Id });
}

Algorytm do zapisania

// this is in the `PersonService` class.
public void Update(PersonViewModel viewModel)
{
Person p = personRepository.GetByPrimaryKey( viewModel.Id );
if (p == null)
return null;

p.PersonName = viewModel.PersonName;


IList<int> existingAssociatedCategories = GetAssociatedCategories( p.PersonId );
foreach( int i in viewModel.AssociatedCategories )
{
if (!existingAssociatedCategories.Contains( i ))
Associate( p.PersonId, i ); // add NEW association in DB
}


foreach( int k in  existingAssociatedCategories)
{
if (!viewModel.AssociatedCategories.Contains( k ))
DeleteAssociation( p.PersonId, k ); // delete existing association
}

repository.UpdatePerson( p ); // save changes to DB for Person object

return p;
}



Daj mi znać, jeśli masz jakieś pytanie.


3 dla odpowiedzi № 5

Zazwyczaj w przypadku czegoś takiego powstrzymałbym się od aktualizacji. Chciałbym usunąć wszystkie wpisy dla danej osoby z PersonCategory, a następnie ponownie wstaw te, które są zapisywane PersonCategory.


1 dla odpowiedzi № 6

Odpowiedzi na twoje pytania brzmią: tak, dodaj / usuń je tam, gdzie dodano / usunięto, i tak.

Jest to relacja wiele do wielu, która jest reprezentowana relacyjnie za pomocą tabeli łączy.