0

我正在建立一个 Umbraco 8 网站并且遇到了一些奇怪的行为。该项目使用.NET 4.7.2。

基本上,我有一个 IENumerable 类型Event,一个简单的内容列表,我想渲染到一个列表中。但是,每当我对列表(有项目)做任何事情时,列表都会立即被清空。这包括简单地分配给不同的变量、检查 null 等。

我不相信这是 Umbraco 8 的问题,但为了清楚起见,我目前正在通过 Surface Controller 运行并通过在我的视图中调用以下内容来呈现它:

@Html.Action("RenderUpcoming", "Events")

这是控制器:

using Index.Models.Events;
using Index.Models.PublishedContent;
using Papermoon.Umbraco.Kupo.Core.Services.Interfaces;
using System;
using System.Linq;
using System.Web.Mvc;
using Umbraco.Web.Mvc;

namespace Index.Web.Controllers.Surface
{
    public class EventsController : SurfaceController
    {
        private readonly KupoGeneralSettings _kupoGeneralSettings;

        public EventsController(IKupoSettingsService kupoSettingsService)
        {
            _kupoGeneralSettings = kupoSettingsService.GetSettings<KupoGeneralSettings>("kupoGeneralSettings");
        }

        public ActionResult RenderUpcoming()
        {
            UpcomingEventsModel model = new UpcomingEventsModel();

            model.Title = "Upcoming Events";

            model.Events = Umbraco.ContentAtXPath("root/homepage/events/event").Select(x => new Event(x));

            model.Events = model.Events.Where(x => x.StartDate > DateTime.Now).OrderBy(x => x.StartDate).Take(3);

            model.TotalEvents = model.Events.Count();

            model.EventListingLink = _kupoGeneralSettings.EventListingLink;

            return PartialView("~/Views/Partials/Events/UpcomingEvents.cshtml", model);
        }
    }
}

所以在这里,当我打电话时model.Events = model.Events.Where(x => x.StartDate > DateTime.Now).OrderBy(x => x.StartDate).Take(3);- 我有结果然后当我做model.TotalEvents = model.Events.Count();列表(model.Events)然后是空的。

当我分配给另一个变量时,当我调用时model.Events.Any(),或者我什至做时,也会发生这种情况Model.Events != null

展示这一点可能比告诉它更容易,所以请参阅此发生的随附 gif:https ://i.imgur.com/rE3VAqe.gif

谢谢,

4

2 回答 2

2

IEnumerable来自这个电话:

Umbraco.ContentAtXPath("root/homepage/events/event")

我不知道它是如何完成的,因为它是 Umbraco 业务,但IEnuemerable它本身允许“懒惰”评估。这意味着,例如,如果您从 SQL 数据库中读取而没有缓冲,则每次迭代时都会读取它。

根据数据,它可以返回相同的结果或新的结果(如果数据已更改)。所以你得到什么IEnumerable完全取决于实现细节,所以如果你重申你不知道幕后发生了什么(从没什么特别的到新的数据库查询)。

为了在来源未知时防止这种行为,IEnumerable您可以ToList()在查询结束时执行以下操作:

Umbraco.ContentAtXPath("root/homepage/events/event")
   .Select(x => new Event(x))
   .ToList();

将发生的情况是您遍历您的集合一次并将所有元素添加到列表中。除非您自己执行此操作,否则此列表不会更改。

于 2019-04-29T13:46:28.993 回答
1

当然——你不知道对象的实际类型,除了它是你可以迭代的东西(an IEnumerable)。

例如,它可能是一个生成器,它返回无限的事物流(好吧,在这种情况下你知道它不是)。

如果你需要一个具体的集合,你可以用.ToList()它来转换成一个List<>你当然可以迭代多次的集合。

于 2019-04-29T13:33:37.507 回答