我正在建立Umbraco 8网站,并且遇到了一些奇怪的行为。该项目正在使用.NET 4.7.2。
基本上,我有一个Event
类型的IENumerable,这是我想呈现到列表中的简单内容列表。但是,只要我对列表(包含项目)执行任何操作,该列表就会立即清空。这包括简单地分配给其他变量,检查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
时,也会发生这种情况。
显示此内容可能比说起来容易,因此请查看发生的情况的相关图片:https://i.imgur.com/rE3VAqe.gif
谢谢
本
答案 0 :(得分: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();
将发生的情况是,您遍历集合一次并将所有元素添加到列表中。除非您自己进行操作,否则此列表不会更改。
答案 1 :(得分:1)
确定–您不知道对象的实际类型,只是可以对其进行迭代(IEnumerable
)。
例如,它可能是一个生成器,它返回无限的事物流(嗯,在这种情况下,您知道不是这样)。
如果您需要具体的集合,则可以使用.ToList()
将其转换为List<>
,当然可以多次迭代。