【问题标题】:.Select with EF Core returns ModelError in View.Select with EF Core 在视图中返回 ModelError
【发布时间】:2020-06-16 03:10:00
【问题描述】:

我想提供一份约会清单以及他们各自的参与者和/或主题。

Planner 模型如下:

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; }
}

我只需要从客户、项目和候选人中选择数量的字段,所以我创建了一个控制器,如下所示:

 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);
    }

在我看来我使用@model IEnumerable&lt;MyProject.Models.Planner&gt;

当不在控制器中应用 .Select-line 时,一切正常,但使用它会产生以下错误:

InvalidOperationException:传递到 ViewDataDictionary 的模型项的类型为 'System.Collections.Generic.List1[&lt;&gt;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]]',但是这个 ViewDataDictionary 实例需要一个类型为'System.Collections.Generic.IEnumerable`1[BeagleNoseV3.Models .Planner]'。

我曾尝试创建一个 ViewModel,但这只会使事情变得更加复杂。我想使用 .Select 创建更高效​​的查询,但我被卡住了。

有什么想法吗?

编辑 ViewModel 场景

我已经尝试过 ViewModel 方法,但是我在如何将 VModel 链接到类方面遇到了困难。

我创建了PlannerVMPlanVMList

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; }
}

我未能在 PlannerController 中提供正确的代码来将 ViewModel 链接到我的数据集 afspraken。有什么想法吗?

【问题讨论】:

  • 查看模型是要走的路。这怎么会“让事情变得更加复杂”?
  • 我正在努力让 ViewModel 方法发挥作用。我将在我的问题中添加一个编辑部分来解释。

标签: sql linq asp.net-core entity-framework-core


【解决方案1】:

您的 afspraken 是匿名列表,您正在将其传递给 View,它期望模型类型为 IEnumerable&lt;MyProject.Models.Planner&gt;

将您的最终 Select 语句更改为:

.Select(s => new MyProject.Models.Planner {
...
})

【讨论】:

  • 我按照你的建议做了,但 Planner 不是 IEnumerable,所以这不起作用。然后我创建了一个 List PlanList 并在 .Select 语句中使用它,但这也不起作用。消息是我 PlanList 是“一个变量,但用作一种类型”,
【解决方案2】:

根据您的要求,显示Planner 及其各自的参与者和/或主题。无需指定.Select

这是一个如下所示的工作演示:

1.型号:

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.查看:

@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.控制器:

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());
}

结果:

【讨论】:

  • 感谢您的帮助。然而,我有点困惑。我已经有针对客户、候选人和项目的课程,我通过public virtual Customer Customer {get; set;} etc. 将它们包括在内,我无法再次重新定义它们。整个目的是从该类中提取单个元素,以免使查询膨胀。
  • redefine them 是什么意思?您只需要像在后端所做的那样搜索对象并包含子元素。然后在视图中选择您想要的单个元素。跨度>
  • 您好,您现在还有问题吗?
  • 很抱歉没有回复您。我放弃。查询工作正常,如果我不使用 .Select 并提取完整实体。我猜这个问题的核心(除了我的编程技能)是如何扩展一个列表,然后在视图中使用它。谢谢你帮助我。
猜你喜欢
  • 2021-12-25
  • 1970-01-01
  • 2017-11-14
  • 2016-10-10
  • 2019-07-22
  • 2021-01-31
  • 1970-01-01
  • 1970-01-01
  • 2019-06-20
相关资源
最近更新 更多