Get object out of List< Tuple < object1, object2 > > and store in ViewModel
[Suggestion: Want to read the answers in a logical manner ?? >> choose TAB [Oldest]
Goal:
Presentation of books with related inventorydetails on homepage
such as Book.Title, InventoryDetail.Quantity etc.
(Join|Book.BookId <=< InventoryDetail.BookId)
Problem 1: Ho开发者_JAVA技巧w to join
Problem 2: How to use a tuple (list of tuples)
Problem 3: How to store the separated objects (from the list of tuples) into a Strongly Typed ViewModel
Answer 1: An possible approach using Mike Brind's Guidance
Answer 2: Problem 1 and 2 tackled !!
Answer 3: Problem 3 tackled !!
Have fun with it. I'm happy to share!!!
public ActionResult Index()
{
// Return a list of tuples {(WebshopDB.Models.Book, WebshopDB.Models.InventoryDetail)}
// Each tuple containing two items:
// > Item1 {WebshopDB.Models.Book}
// > Item2 {WebshopDB.Models.InventoryDetail}
var tuple_booksinventorydetails = ListOfTuples_BookInventoryDetail(5);
// BEGIN UNDER CONSTRUCTION Setting up ViewModel
// See below the code for the ViewModel
var viewmodel = new HomeIndexViewModel()
{
// Problem // Book = tuple_books.Contains(Book).??,
// Problem // InventoryDetail = tuple_books.Contains(InventoryDetail).??
};
// END
return View( ..... );
}
private List<Tuple<Book, InventoryDetail>> ListOfTuples_BookInventoryDetail(int count)
{
var list_of_tuples = new List<Tuple<Book, InventoryDetail>>();
var showbooks = webshopDB.Books
.Join(webshopDB.InventoryDetails, b => b.BookId, i => i.BookId, (b, i) => new { b = b, i = i })
.Where(o => (o.b.ShowInWebshop == true))
.Where(o => o.b.BookThumbUrl.Contains(".jpg"))
.Take(count);
foreach (var item in showbooks)
{
list_of_tuples.Add( Tuple.Create<Book, InventoryDetail>( (item.b), (item.i) ) );
}
return list_of_tuples;
}
As promised! I did reach my goal!!!
<%-- Index.apsx --%>
<%@ Page Title=" <Domain> " Language="C#" MasterPageFile="~/Views/Shared/Store.Master"
Inherits="System.Web.Mvc.ViewPage<HomeTupleIndexViewModel>" %>
<%-- Mandatory 'Import' --%>
<%@ Import Namespace="<Domain>.ViewModels" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
<%--....--%>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<%-- Exerecise Tuple --%>
<% Html.RenderPartial("BookPartial", Model.Book); %>
<% Html.RenderPartial("InventoryDetailPartial", Model.InventoryDetail); %>
</asp:Content>
<%-- BookPartial.ascx --%>
<%-- Currently this ViewPartial is a Strongly Typed ViewPartial %> --%>
<%@ Control Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<IEnumerable< <Domain> .Models.Book>>" %>
<%@ Import Namespace=" <Domain> .Helpers" %>
<%-- Strongly Typed ViewPages--%>
<ul id="...">
<% foreach (var item in Model) {%>
<li>
<div id="...">
<p>
<a href="<%: Url.Action("Details", "Store", new { id = item.BookId }) %>">
<div id="...">
<h2>
<span><%: item.Genre %></span>
</h2>
</div>
<div id="...">
<img alt="<%: item.Title %>" src="<%: item.BookThumbUrl %>" />
</div>
<div id="...">
<span><%: item.Title %></span>
</div>
</a>
</p>
</div>
</li>
<% } %>
</ul>
<%-- InventoryDetailPartial.ascx --%>
<%@ Control Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<IEnumerable< <Domain> .Models.InventoryDetail>>" %>
<%@ Import Namespace=" <Domain> .Helpers" %>
<%-- Strongly Typed ViewPages--%>
<ul id="...">
<% foreach (var item in Model) {%>
<li>
<div id="...">
<p>
<div id="...">
<span>
<% if (item.Quantity == 1)
{ %>
<%: Server.HtmlDecode(Html.Translation("Stock_Amount"))%> <%: item.Quantity %> <%: Server.HtmlDecode(Html.Translation("Copy"))%>
<% }
else if (item.Quantity > 1) %>
<% { %>
<%: Server.HtmlDecode(Html.Translation("Stock_Amount"))%> <%: item.Quantity %> <%: Server.HtmlDecode(Html.Translation("Copies"))%>
<% }
else
{ %>
<%: Server.HtmlDecode(Html.Translation("Sold_Out"))%>
<% } %>
</span>
</div>
</p>
</div>
</li>
<% } %>
</ul>
So, finally I ended up with an Index.aspx calling two separate Partial Views (I prefer to speak about 'controls' instead of 'partials', however, this is just a matter of personal taste).
Compared to Mike Brind's guide (mentioned in my first answer) by using this tuple 'path' guide you'll finally have more 'freedom' to do as you like on the index page. The 'related' objects (!! the 'join' remember !!) are nicely separated in the presentation layer, however still strongly related!
Answer ( Solution for my own posted question! )
// Instantiate new lists needed to add the to be separated objects of the tuple
List<Book> T1 = new List<Book>();
List<InventoryDetail> T2 = new List<InventoryDetail>();
// Iterate through the tuple and add each 'item' of each tuple into the new instantiated lists
for (int i = 0; i < tuple_booksinventorydetails.Count; i++)
{
var tuple = tuple_booksinventorydetails[i];
// Item1
T1.Add(tuple.Item1);
// Item2
T2.Add(tuple.Item2);
}
// Instantiate a new viewmodel to store the separated lists
// ==HomeTupleIndexViewMode Class==
//using System;
//using System.Collections.Generic;
//using <Domain>.Models;
//namespace <Domain>.ViewModels
//{
// public class HomeTupleIndexViewModel
// {
// public List<Book> Book { get; set; }
// public List<InventoryDetail> InventoryDetail { get; set; }
// }
//}
// ==
HomeTupleIndexViewModel tupleviewdata = new HomeTupleIndexViewModel()
{
Book = T1,
InventoryDetail = T2
};
return View(tupleviewdata);
精彩评论