MVC LINQ to SQL JOIN for custom type fails for strongly typed view
I have a simple data model of two tables, email and recipients, email can be sent to one or more recipients.
I set up a database with two tables, created a Linq to SQL repository, created controllers and a strongly typed view.
This works great when I want to select all records from the database
public IList<AllMailDetail> ListAll()
{
var allMail =
from m in _datacontext.mail_receiveds
join r in _datacontext.mail_recipients on m.DeliveryId equals r.DeliveryId
select new AllMailDetail {
DeliveryId = m.DeliveryId,
MessageId = m.MessageId,
SentFrom = m.SentFrom,
FilePath = m.FilePath,
FileName = m.FileName,
SentDateTime = m.SentDateTime,
ReceivedDateTime = m.ReceivedDateTime,
Subject = m.Subject,
SpamScore = m.SpamScore,
IsSpam = m.IsSpam,
SenderIP = m.SenderIP,
Header = m.Header,
SentTo = r.SentTo
};
return allMail.ToList <AllMailDetail>();
}
Custom type class
public class AllMailDetail
{
public int DeliveryId { get; set; }
public int? MessageId { get; set; }
public string SentFrom { get; set; }
public string FilePath { get; set; }
public string FileName { get; set; }
public string SentDateTime { get; set; }
public DateTime ReceivedDateTime { get; set; }
public string Subject { get; set; }
public byte? SpamScore { get; set; }
public bool? IsSpam { get; set; }
public string SenderIP { get; set; }
public string Header { get; set; }
public string SentTo { get; set; }
}
The controller simply pushes the content from the repository into a strongly typed view
public ActionResult Index()
{
return View(_repository.ListAll());
}
In order to get only one record by mail from the database, I have the following code which accepts deliveryId
public IQueryable<AllMailDetail> GetMail(int? id)
{
var allMail =
from m in _datacontext.mail_receiveds
join r in _datacontext.mail_recipients
on m.DeliveryId equals r.DeliveryId
where m.DeliveryId == id
select new AllMailDetail
{
DeliveryId = m.DeliveryId,
MessageId = m.MessageId,
SentFrom = m.SentFrom,
FilePath = m.FilePath,
FileName = m.FileName,
SentDateTime = m.SentDateTime,
ReceivedDateTime = m.ReceivedDateTime,
Subject = m.Subject,
SpamScore = m.SpamScore,
IsSpam = m.IsSpam,
SenderIP = m.SenderIP,
Header = m.Header,
SentTo = r.SentTo
};
return allMail;
}
And its controller code
public ActionResult Details(int? id)
{
var mail = _repository.GetMail(id);
if (mail == null)
return View("NotFound");
return View(mail);
}
I was trying to display the output for one entry, also using a strongly typed view with Inherits = "System.Web.Mvc.ViewPage At the top of the aspx page, but I got the following error
The model item passed to the dictionary is of type "System.Data.Linq.DataQuery`1 [projectMail.Models.AllMailDetail]", but this dictionary requires a model item of type projectMail.Models.AllMailDetail.
I fixed this error after searching many times and found this post most helpful MVC LINQ to SQL Table Join Record Display
so my view is not heavily printed anymore and I create the page like this
<% foreach (projectMail.Models.AllMailDetail item in (IEnumerable)ViewData.Model)
{ %>
...items...
<% } %>
This works great, but it seems like a long way to go. The thing I cannot understand
- Why does the second query have to be IQueryable
- Why didn't it work when the performance was strictly printed
- How to do this to work with a strongly typed view
- This is the best way to work with unions in MVC using LINQ to SQL
source to share