MVC – Passage de plusieurs tables de données à une vue

J’ai actuellement le code suivant dans le HomeController de mon projet MVC:

public class HomeController : Controller { public ActionResult Index() { MyDataContext dc = new MyDataContext(); IQueryable j = from n in dc.Table1 select n; return View(j); } 

Cela fonctionne donc bien, mais je souhaite maintenant passer à un autre tableau avec la même vue. Alors je pensais que je devrais être capable de faire quelque chose comme ça:

 public class HomeController : Controller { public ActionResult Index() { MyDataContext dc = new MyDataContext(); IQueryable j = from n in dc.Table1 select n; IQueryable l = from k in dc.Table2 select k; return View(j, l); } 

Existe-t-il un moyen de faire en sorte que la vue accepte deux modèles de ce type ou, alternativement, un moyen de fusionner les deux jeux de résultats (les deux tableaux ne sont aucunement liés)?

Oui, mais pas tout à fait comme ça. La façon de faire ce que vous voulez faire est de créer une classe ViewModel personnalisée. Cette classe ( MyPageViewModel ) aurait deux propriétés (ou plus), une pour chacun de vos objects. Selon vous, vous y Model.Table1Data aide de Model.Table1Data et Model.Table2Data .

Une classe ViewModel personnalisée est très simple:

 public class MyPageViewModel { public IQueryable Table1Data { get; set; } public IQueryable Table2Data { get; set; } } 

Votre vue doit être fortement typée dans cette classe ViewModel personnalisée.

 <%@ Page Title="MyPage" MasterPageFile="~/Application/Master Pages/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of MyAppNamespace.MyPageViewModel)" %> 

N’essayez pas de taper cela vous-même; Il est plus facile de créer une nouvelle vue et de vérifier la vue “fortement typée”, et de spécifier votre classe New Custom Viewmodel.

Ensuite, votre méthode de contrôleur d’action serait:

 public class HomeController : Controller { public ActionResult Index() { MyDataContext dc = new MyDataContext(); MyPageViewModel vm = new MyPageViewModel(); vm.Table1Data = from n in dc.Table1 select n; vm.Table1Data = from k in dc.Table2 select k; return View(vm); } } 

Oui – créez une nouvelle classe (que vous utiliserez comme modèle) contenant les deux tables:

 public class MyModel { public IQueryable Table1Data { get; set; } public IQueryable Table2Data { get; set; } } 

Ensuite, dans votre contrôleur, initialisez cette classe, renseignez les deux propriétés et envoyez-la à votre vue. Modifiez ensuite la vue pour reconnaître ce nouveau type en tant que modèle de vue.

Pourquoi n’ajoutes-tu pas une classe dans tes modèles pour cela?

 public class MyModel { public j {get; set;} public l {get; set;} } 

Ensuite, vous passez MyModel à la vue sur la tête de la vue.

Sur le contrôleur:

public ActionResult Index () {MyDataContext dc = new MyDataContext ();

  IQueryable j = from n in dc.Table1 select n; IQueryable l = from k in dc.Table2 select k; MyModel myclass = new MyModel(); myclass.j = j; myclass.l = l; return View(myclass); } 

J’ai résolu le problème en créant une liste de “tables” et en la passant à mon modèle de vue. Il s’agit essentiellement d’une liste d’une liste de TransactionEntities. Pour info, ma solution s’appelait DAL, et dans les modèles, j’ai créé une TransactionEntity pour représenter une transaction.

  private TransactionEntity te; private IEnumerable tel1; // A list of TransactionEntities private IEnumerable tel2; private IEnumerable tel3; private IEnumerable> telCollection; 

Je remplis les listes d’entités de transaction (tel1, tel2, tel3) avec mes «lignes», puis j’ajoute les trois objects «tel» (essentiellement une table) à ma telCollection et l’assigne à mon ViewData.Model.

  telCollection = new List>(); telCollection = telCollection.Concat(new[] { tel1 }); telCollection = telCollection.Concat(new[] { tel2 }); telCollection = telCollection.Concat(new[] { tel3 }); ViewData.Model = telCollection; return View(); 

Dans le fichier ASPX, je récupère ensuite la liste et parcourt chaque “table” (ElementAt (#)), créant ainsi trois colonnes différentes, une pour chacune des “tables” principales. BTW, vous pouvez ignorer la variable de compteur.

  <% int counter = 0; %> <% IEnumerable> tranlist = (IEnumerable>)ViewData.Model; %> <% foreach (DAL.Models.TransactionEntity te in tranlist.ElementAt(0)) {.... create rows/columns as needed for the data in a HTML sub-table ......} %>   <% counter = 0; %> <% foreach (DAL.Models.TransactionEntity te in tranlist.ElementAt(1)) {..........} %>   <% counter = 0; %> <% foreach (DAL.Models.TransactionEntity te in tranlist.ElementAt(2)) {..........} %>  

Vous pouvez les transformer en un seul ViewModel:

Définition du modèle:

 public class YourModelName { public IQueryable FirstTableData { get; set;} public IQueryable SecondTableData { get; set;} public YourModelName(IQueryable d1, IQueryable d2) { this.FirstTableData = d1; this.SecondTableData = d2; } } 

Utilisation (dans le contrôleur):

 public ActionResult Index() { MyDataContext dc = new MyDataContext(); IQueryable j = from n in dc.Table1 select n; IQueryable l = from k in dc.Table2 select k; YourModelName model = new YourModelName(j, l); return View(model); } 

En pré-MVC3, j’aurais utilisé un ViewModel et append des propriétés pour chaque object que vous souhaitez que la vue utilise. Si vous utilisez MVC3, je jetterais un coup d’œil à ViewBag .

Un modèle de vue simple:

 public class SomeViewModel { public object Object1 { get; set; } public ssortingng Message { get; set; } } 

Ensuite, dans votre contrôleur, vous transmettez ceci à votre vue:

 var vm = new SomeViewModel { Object1 = coolThing, Message = neatMessage }; return View(vm); 

Vous devrez probablement utiliser ViewModel . Vous définissez la classe, qui contiendra les instances des deux classes souhaitées (+ toutes les propriétés supplémentaires), puis vous utiliserez cela comme modèle.

 class NewViewModel { Table1 T1 {get;set;} Table2 T2 {get;set;} int Anything {get;set;} } 

Ensuite, vous venez de préparer la collection de ces classes ViewModel et d’accéder ultérieurement à leurs instances comme:

 NewViewModel m = new NewViewModel(); var a = m.T1.PropertyA; var b = m.T2.PropertyB; 

etc. Il vous suffit de fusionner toutes les entités dont vous avez besoin dans une classe et d’utiliser cette classe comme modèle dans Controller et View.