I currently have the following code in the HomeController of my MVC project:
public class HomeController : Controller
{
public ActionResult Index()
{
MyDataContext dc = new MyDataContext();
IQueryable<Table1Data> j =
from n in dc.Table1
select n;
return View(j);
}
So that works okay, but now I want to pass a second table through to the same view. So I was thinking I should be able to do something like this:
public class HomeController : Controller
{
public ActionResult Index()
{
MyDataContext dc = new MyDataContext();
IQueryable<Table1Data> j =
from n in dc.Table1
select n;
IQueryable<Table2Data> l =
from k in dc.Table2
select k;
return View(j, l);
}
Is there a way to have the view accept two models like this or, alternatively, a way to merge the two result sets (the two tables are not linked in any way?
Yes there is, but not quite like that. The way to do what you wish to do is to create a custom ViewModel class. This class (MyPageViewModel) would have two (or more) properties, one for each of your objects. In your view, you would access them using Model.Table1Data
and Model.Table2Data
.
A custom ViewModel class is very simple:
public class MyPageViewModel
{
public IQueryable<Table1Data> Table1Data { get; set; }
public IQueryable<Table2Data> Table2Data { get; set; }
}
You view would need to be strongly typed to this custom ViewModel class.
<%@ Page Title="MyPage" MasterPageFile="~/Application/Master Pages/Site.Master"
Inherits="System.Web.Mvc.ViewPage(Of MyAppNamespace.MyPageViewModel)" %>
Don't try to type that youself; easier to create a new view and check "strongly typed" view, and specify your New Custom Viewmodel class.
Then your action Controller method would be:
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);
}
}
Yes - create a new class - which you will use as your model - that contains both tables:
public class MyModel {
public IQueryable<Table1Data> Table1Data { get; set; }
public IQueryable<Table2Data> Table2Data { get; set; }
}
Then, in your controller, initialize this class and populate both properties and send it to your view. Then, modify the view to recognize this new type as the view model.
Why don't you add a class in your models for this?
public class MyModel {
public j {get; set;}
public l {get; set;}
}
Then you pass MyModel to the view on the View's Head.
On the controller:
public ActionResult Index() { MyDataContext dc = new MyDataContext();
IQueryable<Table1Data> j =
from n in dc.Table1
select n;
IQueryable<Table2Data> l =
from k in dc.Table2
select k;
MyModel myclass = new MyModel();
myclass.j = j;
myclass.l = l;
return View(myclass);
}
I solved the problem by creating a list of 'tables' and passing this to my view model. This is essentially a list of a list of TransactionEntities. FYI, my solution was named DAL, and in the models I created a TransactionEntity to represent a transaction.
private TransactionEntity te;
private IEnumerable<TransactionEntity> tel1; // A list of TransactionEntities
private IEnumerable<TransactionEntity> tel2;
private IEnumerable<TransactionEntity> tel3;
private IEnumerable<IEnumerable<TransactionEntity>> telCollection;
I populate the transaction entity lists (tel1, tel2, tel3) with my te 'rows', then add the three 'tel' objects (like a table essentially) to my telCollection and assign this to my ViewData.Model.
telCollection = new List<IEnumerable<TransactionEntity>>();
telCollection = telCollection.Concat(new[] { tel1 });
telCollection = telCollection.Concat(new[] { tel2 });
telCollection = telCollection.Concat(new[] { tel3 });
ViewData.Model = telCollection;
return View();
In the ASPX file, I then get the list and iterate through each 'table' (ElementAt(#)), creating three different columns, one for each of the tal 'tables'. BTW, you can ignore the counter variable.
<td>
<% int counter = 0; %>
<% IEnumerable<IEnumerable<DAL.Models.TransactionEntity>> tranlist =
(IEnumerable<IEnumerable<DAL.Models.TransactionEntity>>)ViewData.Model; %>
<% foreach (DAL.Models.TransactionEntity te in tranlist.ElementAt(0))
{.... create rows/columns as needed for the data in a HTML sub-table ......} %>
</td>
<td>
<% counter = 0; %>
<% foreach (DAL.Models.TransactionEntity te in tranlist.ElementAt(1))
{..........} %>
</td>
<td>
<% counter = 0; %>
<% foreach (DAL.Models.TransactionEntity te in tranlist.ElementAt(2))
{..........} %>
</td>
You could make them both into a single ViewModel:
Model Definition:
public class YourModelName
{
public IQueryable<Table1Data> FirstTableData { get; set;}
public IQueryable<Table2Data> SecondTableData { get; set;}
public YourModelName(IQueryable<Table1Data> d1, IQueryable<Table2Data> d2)
{
this.FirstTableData = d1;
this.SecondTableData = d2;
}
}
Usage (in Controller):
public ActionResult Index()
{
MyDataContext dc = new MyDataContext();
IQueryable<Table1Data> j =
from n in dc.Table1
select n;
IQueryable<Table2Data> l =
from k in dc.Table2
select k;
YourModelName model = new YourModelName(j, l);
return View(model);
}
In pre-MVC3 I would have used a ViewModel and add properties for each object you want the view to use. If you're using MVC3 I'd take a look at ViewBag.
A simple view model:
public class SomeViewModel
{
public object Object1 { get; set; }
public string Message { get; set; }
}
Then in your controller you'd pass this to your view:
var vm = new SomeViewModel { Object1 = coolThing, Message = neatMessage };
return View(vm);
You will probably have to use ViewModel. You define class, that will contain instances of both classes you want (+ any other additional properties), and then you use this as a model.
class NewViewModel {
Table1 T1 {get;set;}
Table2 T2 {get;set;}
int Anything {get;set;}
}
Then you just prepare collection of these ViewModel classes and later access instances of them like:
NewViewModel m = new NewViewModel();
var a = m.T1.PropertyA;
var b = m.T2.PropertyB;
etc.. Just merge all entities you need into one class and use this class as your model in Controller and View.
来源:https://stackoverflow.com/questions/5488363/mvc-passing-multiple-data-tables-to-a-view