代码之家  ›  专栏  ›  技术社区  ›  mark DE Jong

GlassMapper不工作的Sitecore Lucene搜索

  •  1
  • mark DE Jong  · 技术社区  · 7 年前

    过去几周,我一直在努力自学Sitecore。
    目前,我正在尝试创建一个食谱列表,供用户搜索。

    然而,每个食谱都包含配料,Lucene将这些配料作为包含项目ID的字符串返回。我想在代码中有一个配料列表,所以我给了GlassMapper一个机会。

    因此,我通过更改名称将代码中的成分列表从Lucene中排除,使Lucene无法找到该字段。 然后我设置GlassMapper来填充配料表。然而,列表保持为空。

    如何让GlassMapper为我填写此列表?

    我的代码:
    配方类

    [SitecoreType(TemplateId= "{1CF86642-6EC5-4B26-B8A7-1B2EC41F7783}")]
    public class Recipe : SearchResultItem
    {
        [SitecoreId]
        public Guid Id { get { return base.ItemId.Guid; } }
        public virtual string RecipeName { get; set; }
        public virtual string BookName { get; set; }
        public virtual IEnumerable<Ingredient> _Ingredients { get; set; }
        public virtual int AmountOfPeople { get; set; }
    }
    

    [SitecoreType(TemplateId = "{730A0D54-A697-4DAA-908A-279CD24A9F41}")]
    public class Ingredient : SearchResultItem
    {
        [SitecoreId]
        Guid Id { get; }
        [IndexField("Name")]
        public virtual string IngredientName { get; set; }
    }
    

    GlassMapperScCustom类 (我只编辑过这个方法)

        public static IConfigurationLoader[] GlassLoaders()
        {
            var attributes = new SitecoreAttributeConfigurationLoader("Receptenboek");
    
            var loader = new SitecoreFluentConfigurationLoader();
            var config = loader.Add<Recipe>();
    
    
            config.Id(x => x.ItemId);
            config.Info(x => x.Language).InfoType(SitecoreInfoType.Language);
            config.Info(x => x.Version).InfoType(SitecoreInfoType.Version);
    
            config.Field(x => x._Ingredients);
            config.Info(x => x.Uri).InfoType(SitecoreInfoType.Url);
            return new IConfigurationLoader[] {attributes, loader };
    
        }
    

    配方控制器

        [HttpGet]
        public ActionResult Index() 
        {
            List<Recipe> recipes;
            IQueryable<Recipe> query;
    
            string index = string.Format("sitecore_{0}_index", Sitecore.Context.Database.Name);
            var sitecoreService = new SitecoreService(Sitecore.Context.Database.Name);
            string search = WebUtil.GetQueryString("search");
    
            using (var context = ContentSearchManager.GetIndex(index).CreateSearchContext())
            {
                if (!string.IsNullOrEmpty(search))
                {
                    query = context.GetQueryable<Recipe>().Where(p => p.Path.Contains("/sitecore/Content/Home/Recipes/")).Where(p => p.TemplateName == "Recipe").Where(p => p.RecipeName.Contains(search));
                }
                else
                {
                    search = "";
                    query = context.GetQueryable<Recipe>().Where(p => p.Path.Contains("/sitecore/Content/Home/Recipes/")).Where(p => p.TemplateName == "Recipe");
                }
                recipes = query.ToList();
                foreach( var r in recipes)
                {
                    sitecoreService.Map(r);
                    Sitecore.Diagnostics.Log.Audit("SWELF" + r.RecipeName + "- " + r.BookName + " -  " + r.AmountOfPeople + " - " + r.Name + "--" +  r._Ingredients.Count(), this);
    
                }
            }
            RecipesViewModel bvm = new RecipesViewModel() { Recipes = recipes, Search = search };
            return View(bvm);
        }
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   mark DE Jong    7 年前

    在玩了一段时间之后,我决定将我的搜索和映射再拆分一点。我将我的配方模型用于Lucene,并创建了一个ViewModel,用GlassMapper将字段映射到。

    配方类没有更改。
    成分类别没有改变。

    RecipeViewModel类
    映射到此类后,成分列表具有正确的成分量,但其所有字段均为null。 在网上浏览了一下之后,我发现了这篇文章: Why isn't my Enumerable getting populated by Glass.Mapper?

    [SitecoreType(TemplateId = "{1CF86642-6EC5-4B26-B8A7-1B2EC41F7783}", AutoMap = true)]
    public class RecipeViewModel : BaseFields
    {
        [SitecoreId]
        public ID Id { get; set; }
        public virtual string RecipeName { get; set; }
        public virtual string BookName { get; set; }
        [SitecoreField(FieldId = "{D1603482-7CBC-4E55-9CCB-E51DC0FC5A0B}", FieldType = SitecoreFieldType.Multilist)]
        public virtual IEnumerable<IngredientViewModel> Ingredients { get; set; }
        public virtual int AmountOfPeople { get; set; }
    }
    

    配方控制器

        [HttpGet]
        public ActionResult Index()
        {
            List<RecipeViewModel> recipes;
            List<Recipe> query;
    
            string index = string.Format("sitecore_{0}_index", Sitecore.Context.Database.Name);
            var sitecoreService = new SitecoreService(Sitecore.Context.Database.Name);
            string search = WebUtil.GetQueryString("search");
    
            //Search with Lucene
            using (var context = ContentSearchManager.GetIndex(index).CreateSearchContext())
            {
                if (!string.IsNullOrEmpty(search))
                {
                    query = context.GetQueryable<Recipe>().Where(p => p.Path.Contains("/sitecore/Content/Home/Recipes/")).Where(p => p.TemplateName == "Recipe").Where(p => p.RecipeName.Contains(search)).ToList();
                }
                else
                {
                    search = "";
                    query = context.GetQueryable<Recipe>().Where(p => p.Path.Contains("/sitecore/Content/Home/Recipes/")).Where(p => p.TemplateName == "Recipe").ToList();
                }
            }
            //Map to ViewModel
            recipes = query.Select(x => sitecoreService.GetItem<RecipeViewModel>(x.ItemId.Guid)).ToList();
    
            RecipesViewModel bvm = new RecipesViewModel() { Recipes = recipes, Search = search };
            return View(bvm);
        }
    

    还有一个问题
    因为我的ViewModel没有从SearchResultItem继承很多有用的字段,这些字段在映射中丢失了。为了保留SearchResultItem中所需的字段,我为ViewModel创建了一个BaseFields类来继承。我现在只需要Url,但可以用更多字段轻松扩展。

    public class BaseFields
    {
        public virtual string Url { get; set; }
    }