Dantuzzo Dantuzzo - 18 days ago 8
ASP.NET (C#) Question

visual studio mvc 5 creating table with data from different models/tables

I recently started using the vs mvc 5 framework and most tutorials say how to use a single data source for a table in a view, I however would like to make a table in a view which takes data from 2-3 different tables and connects them together, I tried doing it basing on some questions on stackoverflow etc. but nothing seems to works.

There are 3 tables: Contattis, Companies and Contacts, the first one is an sql server table connected with visual studio as .edmx, the last 2 are models created in the application and seeded through it. I want to connect them based on Contact ID.

right at this moment this is the code:

Model:

namespace ContactManager.Models
{
public partial class ContattiDB2 : DbContext
{
public System.Data.Entity.DbSet<ContactManager.Models.Contatti> Contatti { get; set; }
public System.Data.Entity.DbSet<ContactManager.Models.ContactsUni2> ContactsUni2 { get; set; }
}

public partial class ContactsUnified
{
//these are the 3 tables I want to use
public IEnumerable<Contatti> Contattis { get; set; }
public IEnumerable<Companies> Companies { get; set; }
public IEnumerable<Contact> Contacts { get; set; }
}

}


Companies:

namespace ContactManager.Models
{
public class Companies
{
[Key]
public int CompanyId { get; set; }
public string CompanyName { get; set; }
public string CompanyAddress { get; set; }
public string CompanyCity { get; set; }
public string CompanyState { get; set; }
public string CompanyZip { get; set; }
public string CompanyArea { get; set; }
}
}


Contacts:

namespace ContactManager.Models
{
public class Contact
{
[Key]
public int ContactId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
public int CompanyId { get; set; }
}
}


Controller:

namespace ContactManager.Controllers
{
public class ContactsUnifiedController : Controller
{
private ContattiDB2 db2 = new ContattiDB2();
private ApplicationDbContext db = new ApplicationDbContext();

// GET: ContactsUnified
public ActionResult Index()
{
/*var contacts = db.Contacts.ToList();
var companies = db.Companies.ToList();
var contatti = db2.Contattis.ToList();
var view = new ContactsUnified()
{
Contacts = contacts,
Companies = companies,
Contattis = contatti
};
return View(view);*/

var viewModel = new ContactsUni2();
viewModel.Contattis = db.Contattis
.Include(i => i.ContattoID);
viewModel.Contacts = db.Contacts;
viewModel.Companies = db.Companies;
return View(viewModel);
}


The view (This method doesn't work, it says "The model item passed into the dictionary is of type 'ContactManager.Models.ContactsUnified', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[ContactManager.Models.ContactsUnified]'." Though even if it did work I doubt it would display the 3 tables data as required)

@model IEnumerable<ContactManager.Models.ContactsUnified>

@{
ViewBag.Title = "Index";
}

<h2>Contacts Unified</h2>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.Contatti.Nome)
@Html.DisplayNameFor(model => model.Contatti.Citta)
@Html.DisplayNameFor(model => model.Contatti.ContattoID)
@Html.DisplayNameFor(model => model.Contatti.CodicePostale)
@Html.DisplayNameFor(model => model.Contatti.Email)
@Html.DisplayNameFor(model => model.Contact.Address)
@Html.DisplayNameFor(model => model.Contact.CompanyId)
@Html.DisplayNameFor(model => model.Contact.ContactId)
@Html.DisplayNameFor(model => model.Company.CompanyName)

</th>
<th></th>
</tr>

@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Contatti.Nome)
@Html.DisplayFor(modelItem => item.Contatti.Citta)
@Html.DisplayFor(modelItem => item.Contatti.ContattoID)
@Html.DisplayFor(modelItem => item.Contatti.CodicePostale)
@Html.DisplayFor(modelItem => item.Contatti.Email)
@Html.DisplayFor(modelItem => item.Contact.Address)
@Html.DisplayFor(modelItem => item.Contact.CompanyId)
@Html.DisplayFor(modelItem => item.Contact.ContactId)
@Html.DisplayFor(modelItem => item.Company.CompanyName)

</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.ContattoID }) |
@Html.ActionLink("Details", "Details", new { id=item.ContattoID }) |
@Html.ActionLink("Delete", "Delete", new { id=item.ContattoID })
</td>
</tr>
}

</table>




Answer

I think you are required to pass an IEnumerable list from the Index controller, as your view is expecting an IEnumerable<ContactManager.Models.ContactsUnified> list.

In your Index controller try this

public ActionResult Index(String Page)
{
ContactsUnified CU = new ContactsUnified();
CU.Contattis = db.Contattis.Include(i => i.ContattoID);
CU.Contacts = db.Contacts;
CU.Companies = db.Companies;
List<ContactsUnified> contactlist = new List<ContactsUnified>();
contactlist.Add(CU);
return View(contactlist.AsEnumerable());
}

Then in view you can access these items as

<tr>
    <th>
        @Html.DisplayNameFor(model => model.Contatti.Nome)
        @Html.DisplayNameFor(model => model.Contatti.Citta)
        @Html.DisplayNameFor(model => model.Contatti.ContattoID)
        @Html.DisplayNameFor(model => model.Contatti.CodicePostale)
        @Html.DisplayNameFor(model => model.Contatti.Email)
        @Html.DisplayNameFor(model => model.Contact.Address)
        @Html.DisplayNameFor(model => model.Contact.CompanyId)
        @Html.DisplayNameFor(model => model.Contact.ContactId)
        @Html.DisplayNameFor(model => model.Company.CompanyName)

    </th>
    <th></th>
</tr>

But when applying loop it is different than usual i.e you have to apply a loop.

    @foreach (var item in Model)
{
for (int i = 0; i < @item.Contatti.Count(); i++)
{
  <tr>
    <td>
        @item.Contatti[i].Nome
        @item.Contatti[i].Citta
        @item.Contatti[i].ContattoID
        @item.Contatti[i].CodicePostale
        @item.Contatti[i].Email
        @item.Contatti[i].Address
        @item.Contatti[i].CompanyId
        @item.Contatti[i].ContactId
        @item.Contatti[i].CompanyName

    </td>
    <td>
        @Html.ActionLink("Edit", "Edit", new { id=item.Contatti[i].ContattoID }) |
        @Html.ActionLink("Details", "Details", new { item.Contatti[i].ContattoID }) |
        @Html.ActionLink("Delete", "Delete", new { item.Contatti[i].ContattoID })
    </td>
</tr>
  }
 }