查看来自另一个模型的数据会显示DynamicProxies对象

本文关键字:数据 显示 DynamicProxies 对象 模型 另一个 | 更新日期: 2023-09-27 17:51:11

我目前正在一个帮助台系统上工作,并编写一个视图来查看用户的所有票证。

票证由父数据组成,如票证类别、开放用户、技术人员等,然后是具有ticketNotes的子数据。第一个票据注释(在初始创建时添加)是票据描述。在我所看到的票表中,我只想显示每张票的这一个注释(票的描述)。这是我的控制器:

public ActionResult Index()
{
    var model = from t in db.Tickets
                join tn in db.TicketNotes on t.TicketId equals tn.TicketId
                where t.OpenUserId == new Guid("00000000-0000-0000-0000-000000000000")
                orderby t.OpenDate
                select t;
    return View(model);
}

我的视图模型:

namespace HelpDesk.WebUI.ViewModel
{
    public class UserTickets
    {
        public int TicketNumber { get; set; }
        public Guid CategoryId { get; set; }
        public virtual Category Category { get; set; }
        public Guid OpenUserId { get; set; }
        public virtual User OpenUser { get; set; }
        public DateTime OpenDate { get; set; }
        public Guid TechnicianId { get; set; }
        public virtual User Technician { get; set; }
        public Guid TicketStatusId { get; set; }
        public virtual TicketStatus TicketStatus { get; set; }
        public Nullable<DateTime> CloseDate { get; set; }
        public string Note { get; set; }
    }
}

My Models:

namespace HelpDesk.Model
{
    public class Ticket
    {
        public Ticket()
        {
            this.TicketNotes = new HashSet<TicketNote>();
        }
        public Guid TicketId { get; set; }
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Required]
        public int TicketNumber { get; set; }
        [ForeignKey("Category")]
        [Required]
        public Guid CategoryId { get; set; }
        public virtual Category Category { get; set; }
        [ForeignKey("OpenUser")]
        [Required]
        public Guid OpenUserId { get; set; }
        public virtual User OpenUser { get; set; }
        [DataType(DataType.Date)]
        [Required]
        public DateTime OpenDate { get; set; }
        [ForeignKey("Technician")]
        [Required]
        public Guid TechnicianId { get; set; }
        public virtual User Technician { get; set; }
        [ForeignKey("TicketStatus")]
        [Required]
        public Guid TicketStatusId { get; set; }
        public virtual TicketStatus TicketStatus { get; set; }
        [DataType(DataType.Date)]
        public Nullable<DateTime> CloseDate { get; set; }
        public virtual ICollection<TicketNote> TicketNotes { get; set; }
        //public virtual ICollection<TicketSubscription> TicketSubscriptions { get; set; }
    }
}
namespace HelpDesk.Model
{
    public class TicketNote
    {
        public Guid TicketNoteId { get; set; }
        [ForeignKey("Ticket")]
        [Required]
        public Guid TicketId { get; set; }
        public virtual Ticket Ticket { get; set; }
        public string Note { get; set; }
        [Display(Name = "Attachment")]
        public string AttachmentPath { get; set; }
        [MaxLength(255)]
        public string AttachmentName { get; set; }
        [ForeignKey("UserNote")]
        [Required]
        public Guid UserNoteId { get; set; }
        public virtual User UserNote { get; set; }
        [DataType(DataType.Date)]
        [Required]
        public DateTime TicketNoteDate { get; set; }
        [Display(Name = "Private Note")]
        [Required]
        public bool PublicFlag { get; set; }
        public bool Delete { get; set; }
    }
}

我的观点是:

@model IEnumerable<HelpDesk.Model.Ticket>
@{
        ViewBag.Title = "Index";
    }
    <h2>Index</h2>
    <p>
        @Html.ActionLink("Create New", "Create")
    </p>
    <table class="table">
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Category.CategoryName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.OpenUser.FullName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Technician.FullName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.TicketStatus.StatusDescription)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.TicketNumber)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.OpenDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.CloseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.TicketNotes)
            </th>
            <th></th>
        </tr>
    @foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Category.CategoryName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.OpenUser.NTUserName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Technician.NTUserName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.TicketStatus.StatusDescription)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.TicketNumber)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.OpenDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.CloseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.TicketNotes.OrderBy(t=t.TicketId).First().TicketText)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id=item.TicketId }) |
                @Html.ActionLink("Details", "Details", new { id=item.TicketId }) |
            </td>
        </tr>
    }
    </table>

除了从TicketNote模型中提取的票券外,其他都可以工作。对于这个字段,我得到

System.Data.Entity.DynamicProxies.Ticket_BA0BCDE55BCBE6BA2FE66FAD697C8D2C0D7AAD7C5F797406642720CB57DA2A89

根据一个人的建议,我将控制器中的代码更改为:

public ActionResult Index()
    {
        var model = db.Tickets
                    .Include(t=>t.TicketNotes)
                    .Where(t.OpenUserId == new Guid("00000000-0000-0000-0000-000000000000"))
                    .OrderBy(t => t.OpenDate);
        return View(model);
    }

和我的视图建议,但我得到一个错误在这一行在视图:

@Html.DisplayFor(modelItem => item.TicketNotes.OrderBy(t=t.TicketId).First().TicketText)

表示在当前上下文中不存在名称't'

查看来自另一个模型的数据会显示DynamicProxies对象

(可选)在您的控制器中使用此选项以获得更好的性能,因为它将主动加载TicketNotes而不是惰性加载它们:

public ActionResult Index()
{
    var model = db.Tickets
                  .Include(t=>t.TicketNotes)
                  .Where(t.OpenUserId == new Guid("00000000-0000-0000-0000-000000000000"))
                  .OrderBy(t=>t.OpenDate);
    return View(model);
}

并在你的视图中使用这个(它将与渴望和懒惰加载的注释一起工作):

@Html.DisplayFor(modelItem => item.TicketNotes.OrderBy(t=t.TicketId).First().TicketText)

似乎您正在使用LazyLoading与您的实体模型,因此数据的实际类型不是您的Ticket,而是由EntityFramework动态生成的一些数据类型,处理实际加载细节。

您可以:

  1. 禁用LazyLoading使Ticket保持为Ticket。但是在这种情况下,你必须手动加载所有相关的实体。
  2. 或者手动渲染所需的部分视图(显示模板)。