【问题标题】:Viewing data from another model results in DynamicProxies object being shown查看来自另一个模型的数据会导致显示 DynamicProxies 对象
【发布时间】:2015-05-29 15:31:38
【问题描述】:

我目前正在开发一个帮助台系统并编写一个视图来查看用户的所有工单。

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

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

    }
}

我的模特:

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'在当前上下文中不存在。

【问题讨论】:

  • 您的 Linq 查询有点毫无意义,因为您只选择了票证而不选择票证。稍后通过延迟加载将这些笔记拉入。

标签: c# asp.net-mvc linq visual-studio razor


【解决方案1】:

(可选)在您的控制器中使用它以获得更好的性能,因为它会急切地加载您的 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)

【讨论】:

    【解决方案2】:

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

    你可以:

    1. 要么disable the LazyLoading,所以Ticket 保持为Ticket。但在这种情况下,您将不得不加载所有 related entities manually
    2. manually render desired partial views(display templates)

    【讨论】:

    • 我在原始帖子中添加了更多信息。有人知道我为什么会收到错误消息吗?
    • @djblois 好吧,如果不是复制错误,则表示您在 lambda 表达式中忘记了尖括号 - item.TicketNotes.OrderBy(t=t.TicketId) 应为 item.TicketNotes.OrderBy(t =&gt; t.TicketId)
    • 感谢工作。抱歉,在我的新工作中学习 MVC 让我不知所措。我的老板告诉我他会教我,但我完全靠自己学习。
    • @djblois 相信我,我非常了解你。下次要更加专心——这不是一些框架特质,而是一个小错字。祝你好运。
    • Eugene 我从上面的另一张海报上复制了它,这是他们的错字。一开始我也以为是我的错。
    猜你喜欢
    • 1970-01-01
    • 2014-08-05
    • 2019-11-04
    • 1970-01-01
    • 2018-10-13
    • 1970-01-01
    • 2017-05-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多