NHibernate.Search + Lucene.NET重复条目

时间:2011-01-10 11:38:49

标签: .net lucene.net nhibernate.search

当我从现有数据库构建初始索引时,Lucene中的条目类型被索引为< _hibernate_class:Castle.Proxies。 MuestraProxy ,DynamicProxyGenAssembly2>

但是,当使用NHibernate添加新实体时,它会被索引为< _hibernate_class:RALVet.Model。 Muestra ,RALVet>},它会在Lucene中创建重复的条目,一个作为真正的类,另一个作为其代理人。

我在构建索引时尝试过使用NHibernateUtil.GetClass(),但它仍然会返回代理。

这是构建初始索引的代码:

private static void CreateIndex<T>()
    {
        var fullTextSession =
            NHibernate.Search.Search.CreateFullTextSession(BootStrapper.SessionFactory.OpenSession());
        using(var tran = fullTextSession.BeginTransaction())
        {
            var query = fullTextSession.CreateQuery(string.Concat("from ", typeof (T).Name));

            foreach (var doc in query.List())
            {
                fullTextSession.Index(doc);
            //  fullTextSession.Index(NHibernateUtil.GetClass(doc));
            }
            tran.Commit();
        }
        fullTextSession.Close();
    }

2 个答案:

答案 0 :(得分:0)

编辑2:嗯,我在SO上做了另一次搜索,我认为你应该看看this answer。我无法重现你的问题,所以这里有其他的东西(你的配置或域模型吗?)或者我完全忽略了这一点。祝你好运!


我将尝试猜测这里的原因(我不使用C#或hql,所以如果它是这个领域的东西,我可能会运气不好)。我认为你看到的是因为你使用.List()方法的无类型版本。您应该尝试使用.List<T>()来指定列出实体时所期望的类型。

我认为

  

foreach(query.List <T>()中的var doc){       fullTextSession.Index(DOC); }

应该这样做。


编辑:好吧所以显然它不适用于添加的<T>(显然代码片段使用括号,所以如果你这样做,请确保你复制粘贴正确的版本。)

FWIW,我们在工作中所做的工作如下。我们使用UnitOfWork模式,因此UnitOfWork启动当前的Nhibernate配置和会话。我使用Reflector从Vb.net转到c#

            DocumentBuilder db = SearchFactoryImpl.GetSearchFactory(UnitOfWork.Configuration).GetDocumentBuilder(typeof(T));
            IList<T> results = null;
            PropertyInfo pi = typeof(T).GetProperty("Id");
            // an internal method that pages the data from the DB, returning true while there's more to process
            while (this.InnerPageThrough<T>(ref results, pageNumber, itemsPerPage))
            {
                IndexWriter iw = new IndexWriter(this.CheminIndexation + @"\" + typeof(T).Name, new StandardAnalyzer(), false);
                iw.SetMaxMergeDocs(0x186a0);
                iw.SetMergeFactor(0x3e8);
                iw.SetMaxBufferedDocs(0x2710);
                iw.SetUseCompoundFile(false);
                using (Timer.Start("indexing + Conversions.ToString(results.Count) + " objects " + typeof(T).Name))
                {
                    // Sorry, looks like crap through the translation
                    IEnumerator<T> VB$t_ref$L3;
                    try
                    {
                        VB$t_ref$L3 = results.GetEnumerator();
                        while (VB$t_ref$L3.MoveNext())
                        {
                            T Entity = VB$t_ref$L3.Current;
                            object EntityId = RuntimeHelpers.GetObjectValue(pi.GetValue(Entity, null));
                            iw.AddDocument(db.GetDocument(Entity, RuntimeHelpers.GetObjectValue(EntityId), typeof(T)));
                        }
                    }
                    finally
                    {
                        if (VB$t_ref$L3 != null)
                        {
                            VB$t_ref$L3.Dispose();
                        }
                    }
                }
                iw.Flush(true, true, true);
                iw.Close();
                UnitOfWork.CurrentSession.Clear();
                pageNumber++;
            }
            if (Optimize)
            {
                using (Timer.Start("optimising index"))
                {
                    IndexWriter iw = new IndexWriter(this.CheminIndexation + @"\" + typeof(T).Name, new StandardAnalyzer(), false);
                    iw.Optimize();
                    iw.Close();
                }
            }
        }
    }
}

我将尝试以更精简的方式重现你的问题

答案 1 :(得分:0)

好的,我终于完美地完成了它。

问题是我使用拦截器在我的实体中注入INotifyPropertyChanged实现。删除拦截器使NH.Search和Lucene.net很好地工作。