Click here to Skip to main content
14,239,736 members
Rate this:
Please Sign up or sign in to vote.
See more:
I am using asp.nt mvc 5 ,linq

i have a two tables
order
payment


    List<Order> order=new List<Order>(repository.Get()).ToList());
      

     List<Payment> payment=new List<Payment>(repository.Get()).ToList());

      List<orderPaymentViewModel> ordrPaymt = new List<orderPaymentViewModel>();
             ordrPaymt =order.AddRange(payment);

return view(Tuple.Create(ordrPaymt));


i want to pass these two lists to a view and then want to iterate using a freach

i.e
@foreach(var item in Model.item1)
{
orderData   paymentData
1              1
2              2
3              3


}

there is no relation between data..the main requirement is to display them side by side in say two colmns
Posted
Updated 23-Nov-14 10:24am
v3
Comments
BillWoodruff 23-Nov-14 11:54am
   
You have a list of Orders, and a list of Payments: is there a "relationship" of some kind between the items ? If there's no relationship, sure, throw them all in new list, but, if there's a relationship, we need to know what that is and how you wish to preserve that in the new list.
Member 9129971 23-Nov-14 15:50pm
   
currenlty there is no relationship
Member 9129971 23-Nov-14 15:52pm
   
acutally i want to loop through them using the sinlge loop but for that i need them in one list, but concat,zip,union are not working for me ,so what should i do
Maciej Los 23-Nov-14 14:06pm
   
Is there any relationship between data?
Member 9129971 23-Nov-14 15:52pm
   
no
BillWoodruff 23-Nov-14 17:14pm
   
To display them side-by-side means you must distinguish between the two, and if they are just all lumped into the same List, that's only possible if you provide a way, when you iterate the merged List, to distinguish between the two: I call that a "relationship."

But, if all you are going to do is to merge the two lists so you can display a structured output: why merge them ?
Rate this:
Please Sign up or sign in to vote.

Solution 2

Passing two lists to a view is really easy. You can use the ViewBag or you can simply create a custom or dynamic model having the two list. That's it.

But the question is how you intend to traverse these two. As BillWoodruff asked, you probably have some relations between these two. And at that point I wouldn't pass two lists to the view - only if you want to show all the data in your repository on one web page (I doubt you want this). If by any chance you want to filter the data in the view, and use the relation you might have, you have introduced a huge overhead - this is not the concern of the view! It is agains MVC concepts. You have to consider also, that EF for example is returning IEnumerables, which are not enumerated until you traverse them. Making lists out of them means that you read all the data into memory. This is a huge mistake in a production scenario. Pass lists only if you really need to, or if they are short ones in every case.

I don't know what you repository is. I would recommend using EF and the navigator possibilities which it has, sou you can simply manage and navigate trough the relations between the entities of your model. And in the same time you can make use of the deferred execution.

[Update based on the chat below]
There is a method you can use to traverse two IEnumerables in parallel. You can evaluate it and adapt to your needs.

IEnumerable orders = new int[] {1,2,3,4};
IEnumerable payments = new int[] {30,31,32,33,34,35};
 
var oe = (IEnumerator)orders.GetEnumerator();
var pe = (IEnumerator)payments.GetEnumerator();
 
bool no, np;
while((no = oe.MoveNext()) | (np = pe.MoveNext()))
{
Console.WriteLine(String.Format("<tr><td>{0}</td><td>{1}</td></tr>", 
no ? ((int)oe.Current).ToString() : "&nbsp;",
np ? ((int)pe.Current).ToString() : "&nbsp;"
));
 
}
   
v2
Comments
Member 9129971 23-Nov-14 16:00pm
   
actually i want to display them in lets say for example two columns i.e
@foreach(var item in Model.orderPayment)
orderData paymentData
<tr><td>1</td> <td>1</td></tr>
<tr><td>1</td> <td>1</td></tr>
<tr><td>1</td> <td>1</td></tr>

and that is possible only if i have only 1 list which contains both order and payment data....
Zoltán Zörgő 23-Nov-14 16:06pm
   
And how can you tell, which orderData comes aside which paymentData? That is thel relation we are all asking about....
Member 9129971 23-Nov-14 16:18pm
   
actually there is no relation means there could be any data that can be displayed in the second column against first,,,in short there is no relation...its just a play of tr td..but i have no way to display this data except to wrap them in a single list and then iterating them
Member 9129971 23-Nov-14 16:13pm
   
actually there is no relation means there could be any data that can be displayed in the second column against first,,,in short there is no relation...its just a play of tr td..but i have no way to display this data except to wrap them in a single list and then iterating them
Member 9129971 23-Nov-14 16:16pm
   
for example if i have to display the data in differnt rows then i can simply display them using two lists ie two foeach loops but here i have a scenario where i have to dispaly them in a colmn so how i can display data in colmn using two foreach loops...i hope u understand what i want to say
Zoltán Zörgő 23-Nov-14 16:23pm
   
No problem, but you understand, that if you have 1000 rows in Orders and 2000 rows in Payments, than you have 2 million rows as result? I can't imagine, that this is what you want....

Or you want order 1 sibe-by-side with payment 1, order 2 with payment 2, 3 with 3 and so on? In this case you have to be sure, that there are equal number of orders and payments.
Member 9129971 23-Nov-14 16:26pm
   
no if i have 1000 rows in orders and 2000 rows in payments then it would be total 2000 rows..
Zoltán Zörgő 23-Nov-14 16:28pm
   
Ok so you want them side-by side? And if one is longer, your table goes longer. That is what you want?
Member 9129971 23-Nov-14 16:29pm
   
no no ..lets for example i have following data
order
1
2
3

payment
3
4
5

then the list would contain 1,2,3,4,5,6
means total 3 rows and if its not possible to achieve 3 rows then 6 rows
Zoltán Zörgő 23-Nov-14 16:31pm
   
Than your previous calculation is wrong, since 2000 after 1000 gives 3000...
So: you want one list after the other?
Member 9129971 23-Nov-14 16:33pm
   
no it calculations are not wrong ..my comment is wrong...i have edited...
Zoltán Zörgő 23-Nov-14 16:35pm
   
So you want to show a list of orders, and a list of payments - one aside the other, but with no logical connection between the rows of those lists?
Member 9129971 23-Nov-14 16:35pm
   
to make simple ...
i want something like this
foeach(var in orderpayment)
{}

if its not possible by merging a list then how can i do this...what viewmodel should i create?
Zoltán Zörgő 23-Nov-14 16:42pm
   
Is the visualization your problem? You can't put them side by side?
Forget the model for a second.
Just add:
ViewBag.Payment = payment;
ViewBag.Order = order;

return View();


So you have both lists in the view. Not in the model, but does not really matter. You could make a viewmodel like this:

public class PaymentOrdersViewModel
{
public List<order> orders {get;set;}
public List<Payment> payments {get;set;}
}
</order>

and than populate an instance of this class...

return View{new PaymentOrdersViewModel { orders = order, payments = payment} }
Member 9129971 23-Nov-14 16:48pm
   
the same problem arises here i have to use two foreachs
foeach(var item in viewbag.order)
{rows....
.......
......}
foeach(var item in viewbag.payment)
{rows...
rows...}

so they are in diffent rows not columns????
Member 9129971 23-Nov-14 16:50pm
   
also if u use paymentorderViewmodel
then i u have to use
foeach(paymentorderviewmodel.order)
{}
then
foreach(paymentorder.payment)
{}
same problem
Zoltán Zörgő 23-Nov-14 16:52pm
   
Imagine this:

<table>
<tr>
<td>
Table with foreach for orders
</td>
<td>
Table with foreach for payments
</td>
</tr>
</table>

You migth traverse the two lists one after the other, but at the end you will see them side by side.

But there is a method to traverse the list step by step. You can do also that, but you gain nothing.
Member 9129971 23-Nov-14 16:56pm
   
i have 12 colmns in total ...
6 colmn for order and 6 for payment
so it is not possible to display them in a sinlge td
ie

orderid orderno amount discount paymentid paymetno amount paid disocount etc etc....so same it cannot be used
Zoltán Zörgő 23-Nov-14 16:59pm
   
Of course you can, TABLE in TABLE! The outer TD is just a container for the inner TABLE. Still, this won't really work if you need wrapping. Just wait a few moments, I will post a solution how to traverse two lists in parallel.
Member 9129971 23-Nov-14 17:06pm
   
do u have any idea how to do this using
addrange() method???
ie
resltlist=order.addrange(payment);
Member 9129971 23-Nov-14 17:09pm
   
it would give me 6 rows 3 for order 3 for payment
but i only want 3 rows
Zoltán Zörgő 23-Nov-14 17:15pm
   
Look at the follwing code:

IEnumerable orders = new int[] {1,2,3,4};
IEnumerable payments = new int[] {30,31,32,33,34,35};

var oe = (IEnumerator)orders.GetEnumerator();
var pe = (IEnumerator)payments.GetEnumerator();

bool no, np;
while((no = oe.MoveNext()) | (np = pe.MoveNext()))
{
Console.WriteLine(String.Format("<tr><td>{0}</td><td>{1}</td></tr>",
no ? ((int)oe.Current).ToString() : "&nbsp;",
np ? ((int)pe.Current).ToString() : "&nbsp;"
));

}

You can try it in LinqPad - as you will see, it is traversing the two lists in parallel. It will be not hard to generate the row not for ints, but objects with more properties to display. It looks not neat as it is, but there you can build a heloper on top of it.
Zoltán Zörgő 24-Nov-14 4:38am
   
Any progress? If you find my answer helpful feel free to accept it.
Zoltán Zörgő 30-Nov-14 7:55am
   
Any progress? If you have found my answer of use, feel free to accept it!
BillWoodruff 24-Nov-14 18:20pm
   
+5 with gold-star for persistence and patience :)
Zoltán Zörgő 25-Nov-14 2:21am
   
Thank you :)
Rate this:
Please Sign up or sign in to vote.

Solution 3

There is few ways to merge 2 lists:
1) you can use Union method[^]
or
2) you can join two list[^] via linq query.


[Edit]
Here is simple example:
void Main()
{
	List<Order> orders = new List<Order> {
			new Order(31),
			new Order(32),
			new Order(33),
			new Order(34)};

	List<Payment> payments = new List<Payment>  {
			new Payment(1, 30),
			new Payment(2, 31),
			new Payment(3, 32),
			new Payment(4, 33),
			new Payment(5, 34),
			new Payment(6, 35)};

	var qry = from o in orders
		join p in payments on o.OrderId equals p.OrderId
		select new{o.OrderId, p.PaymentId};
	
	foreach(var op in qry)
	{
		Console.WriteLine("OrderId={0}; PaymentId={1}", op.OrderId, op.PaymentId);
	}
}

// Define other methods and classes here
public class Order
{
	private int orderid = 0;
	//constructor
	public Order(int ordid)
	{
		orderid = ordid;
	}
	
	public int OrderId
	{
		get
		{
			return orderid;
		}
		set
		{
			orderid = value;
		}
	}
}

public class Payment
{
	private int paymentid = 0;
	private int orderid = 0;
	
	public Payment(int payid, int ordid)
	{
		paymentid = payid;
		orderid = ordid;
	}
	
	public int PaymentId
	{
		get
		{
			return paymentid;
		}
		set
		{
			paymentid = value;
		}
	}

	public int OrderId
	{
		get
		{
			return orderid;
		}
		set
		{
			orderid = value;
		}
	}
}

Result:
OrderId=31; PaymentId=2
OrderId=32; PaymentId=3
OrderId=33; PaymentId=4
OrderId=34; PaymentId=5
   
v2
Comments
Member 9129971 23-Nov-14 16:01pm
   
have seen them but did not solved my prblem giving me following error:
Error 9 'System.Collections.Generic.List' does not contain a definition for 'Concat' and the best extension method overload 'System.Linq.Queryable.Concat(System.Linq.IQueryable, System.Collections.Generic.IEnumerable)' has some invalid arguments

same for union

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100