.Select with EF Core returns ModelError in View

asp.net-core entity-framework-core linq sql

Question

I want to present a list of appointments together with their respective participants and/or subjects.

The Planner model is as follows:

public class Planner : BaseEntity
{        
    public int? ProjectCandId { get; set; }
    public int? CandidateId { get; set; }        
    public int? ProjectId { get; set; }
    public int? CustomerId { get; set; }        

    public DateTime PlanDatum { get; set; }
    public string Location { get; set; }        
    public string Description { get; set; }

    public virtual Customer Customer { get; set; }
    public virtual Candidate Candidate { get; set; }
    public virtual Project Project { get; set; }
    public virtual ProjectCand ProjectCand { get; set; }
}

I only require a select number of fields from Customer, Project, and Candidate, so I created a controller which looks like:

 public async Task<IActionResult> Index()
    {
       var afspraken = await _context.Planner
            .Include(c => c.Customer)
            .Include(c => c.Project)
            .Include(c => c.Candidate)
            .Select(s => new { s.Id, s.CandidateId, s.CustomerId, s.Description,  s.IsDeleted, s.Location, s.PlanDatum, 
                s.Customer.CompanyName, 
                s.Project.ProjectTitle, 
                s.Candidate.FullName })
            .ToListAsync().ConfigureAwait(false);
        return View(afspraken);
    }

I use in my view @model IEnumerable<MyProject.Models.Planner>.

When NOT applying the .Select-line in the controller everything works just fine, but with it, it generates the following error:

InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'System.Collections.Generic.List1[<>f__AnonymousType710[System.Int32,System.Nullable1[System.Int32],System.Nullable1[System.Int32],System.String,System.Boolean,System.String,System.DateTime,System.String,System.String,System.String]]', but this ViewDataDictionary instance requires a model item of type 'System.Collections.Generic.IEnumerable`1[BeagleNoseV3.Models.Planner]'.

I have tried to create a ViewModel, but that complicated things only more. I would like to use the .Select to create a more efficient query, but I am stuck.

Any thoughts?

EDIT ViewModel Scenario

I have tried the ViewModel-approach, but there I struggled on how to link the VModel to the Class.

I created PlannerVM and PlanVMList:

public class PlannerVM : BaseEntityVM  //BaseEntityVM provides Id, IsDeleted and some other administrative elements
{
    public int? ProjectCandId { get; set; }
    public int? CandidateId { get; set; }
    public int? ProjectId { get; set; }
    public int? CustomerId { get; set; }

    public DateTime PlanDatum { get; set; }
    public string Location { get; set; }        
    public string Description { get; set; }
    public string CandidateFullName { get; set; }
    public string ProjectCode { get; set; }
    public string ProjectTitle { get; set; }
    public string CompanyName { get; set; }
}

public class PlanVMList
{
    public List<PlannerVM> AppointList { get; set; }
}

I fail to come up with the right code in the PlannerController to link the ViewModel to my dataset afspraken. Any thoughts?

1
0
3/6/2020 1:29:08 PM

Popular Answer

From your requirement,to display Planner together with their respective participants and/or subjects.No need to specify the .Select.

Here is a working demo like below:

1.Model:

public class BaseEntity
{
    public int Id { get; set; }
    public bool IsDeleted { get; set; }
}
public class Planner : BaseEntity
{
    public int? ProjectCandId { get; set; }
    public int? CandidateId { get; set; }
    public int? ProjectId { get; set; }
    public int? CustomerId { get; set; }

    public DateTime PlanDatum { get; set; }
    public string Location { get; set; }
    public string Description { get; set; }

    public virtual Customer Customer { get; set; }
    public virtual Candidate Candidate { get; set; }
    public virtual Project Project { get; set; }
}  
public class Customer: BaseEntity
{
    public string CompanyName { get; set; }
}
public class Candidate: BaseEntity
{
    public string FullName { get; set; }
}
public class Project: BaseEntity
{
    public string ProjectTitle { get; set; }
}

2.View:

@model IEnumerable<Planner>
<h1>Index</h1>
<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Id)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.CandidateId)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.CustomerId)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.PlanDatum)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Location)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Description)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Customer)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Candidate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Project)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.IsDeleted)
            </th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Id)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.CandidateId)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.CustomerId)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.PlanDatum)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Location)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Description)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Customer.CompanyName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Candidate.FullName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Project.ProjectTitle)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.IsDeleted)
            </td>
        </tr>
}
    </tbody>
</table>

3.Controller:

public async Task<IActionResult> Index()
{
    var model = _context.Planner.Include(p => p.Candidate).Include(p => p.Customer).Include(p => p.Project);
    return View(await model.ToListAsync());
}

Result: enter image description here

0
3/4/2020 6:06:41 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow