Sitecore Lucene Search With GlassMapper not working

时间:2017-10-12 09:58:01

标签: c# sitecore sitecore8 glass-mapper

I have been trying to teach myself Sitecore for the past couple of weeks.
At the moment i am trying to create a list of Recipes for users to search through.

However every Recipe contains Ingredients, Lucene returned these Ingredients as strings containing Item ID's. I wanted to have a List of Ingredients in my code so i gave GlassMapper a shot.

So i excluded the Ingredient list in my code from Lucene by changing the name so Lucene couldn't find the field. I then set-up GlassMapper to fill the Ingredient list. The list stays null however.

How do i make GlassMapper fill this list for me?

My code:
Recipe class

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

Ingredient class

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

GlassMapperScCustom class (I've only edited this method)

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

    }

Recipe Controller

    [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 个答案:

答案 0 :(得分:0)

玩了一会儿后,我决定将我的搜索和映射分开一点。我使用我的Recipe模型和Lucene创建了一个ViewModel来将字段映射到GlassMapper。

食谱课没有改变 成分类没有改变。
不需要GlassMapperScCustom类,所以我恢复了它的默认值。

RecipeViewModel类
映射到此类后,成分列表具有正确数量的成分,但其​​所有字段均为空。 在互联网上四处查看后,我发现了这个stackoverflow帖子:Why isn't my Enumerable getting populated by Glass.Mapper?
我决定给SitecoreFieldType一个去,它就行了!

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

配方控制器
事实证明,这是错误的方式。我找到了使用SitecoreService.GetItem&lt;&gt;()

将列表映射到另一个列表的示例
    [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; }
}