Ho bisogno di una guida sulle migliori pratiche.
Ho due tabelle SQL, una chiamata Persona checontiene PersonId, PersonName e un'altra categoria chiamata che contiene CategoryId, CategoryName. Le categorie possono essere piuttosto numerose e aggiunte occasionalmente.
Voglio una vista di creazione che mostri una casella di testo per PersonName e quindi una singola casella di controllo per ciascuna delle categorie nella tabella Categoria.
L'utente può inserire un nome e spuntare tutte le caselle di controllo della categoria che desidera e quindi salvare.
È l'approccio corretto per inserire il PersonNamenella tabella Persona e quindi inserire una voce per ogni combinazione persona / categoria in una nuova tabella denominata PersonCategory che ha i campi PersonId e CategoryId?
Se lo faccio, come posso gestire gli aggiornamenti se le categorie vengono modificate nella vista di modifica? Questa è una categoria che può essere deselezionata contro una persona. Il record in PersonCategory deve essere eliminato?
risposte:
1 per risposta № 1Questo è come lo faccio. Esaminerò quanto segue.
- Visualizza modello
- ASP.NET MVC View (interfaccia utente)
- Metodo di controllo post azione
- Algoritmo da salvare
Visualizza modello
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; }
}
ASP.NET MVC View
<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>
Metodo di azione post controller
[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 });
}
Algoritmo da salvare
// 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;
}
Fammi sapere se hai qualche domanda.
3 per risposta № 2
In genere, per qualcosa del genere, mi asterrei dagli AGGIORNAMENTI. Vorrei eliminare tutte le voci per una determinata persona da PersonCategory
e quindi reinserire quelli che vengono salvati PersonCategory
.
1 per risposta № 3
Le risposte alle tue domande sono sì, aggiungile / eliminale dove aggiunto / rimosso e sì.
Questa è una relazione molti-a-molti, che è rappresentata relazionalmente usando una tabella di collegamenti.
1 per risposta № 4
Questo è come lo faccio. Esaminerò quanto segue.
- Visualizza modello
- ASP.NET MVC View (interfaccia utente)
- Metodo di controllo post azione
- Algoritmo da salvare
Visualizza modello
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; }
}
ASP.NET MVC View
<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>
Metodo di azione post controller
[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 });
}
Algoritmo da salvare
// 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;
}
Fammi sapere se hai qualche domanda.
3 per risposta № 5
In genere, per qualcosa del genere, mi asterrei dagli AGGIORNAMENTI. Vorrei eliminare tutte le voci per una determinata persona da PersonCategory
e quindi reinserire quelli che vengono salvati PersonCategory
.
1 per risposta № 6
Le risposte alle tue domande sono sì, aggiungile / eliminale dove aggiunto / rimosso e sì.
Questa è una relazione molti-a-molti, che è rappresentata relazionalmente usando una tabella di collegamenti.