2013-03-02 88 views
0

我有一个Lucene FT引擎,我在我的NHibernate项目上实现。我试图做的一件事是支持定期维护,即清理FT索引并从持久化实体重建。我构建了一个泛型静态方法PopulateIndex<T>,它可以派生实体的类型,查找全文索引列的属性属性,并将它们存储到Lucene目录中。现在我的问题是如何从NHibernate方面提供强类型的IEnumerable<T>NHibernate返回基于Reflection.Type的强类型IEnumerable类型

public static void PopulateIndex<T>(IEnumerable<T> entities) where T : class 
{ 
    var entityType = typeof(T); 
    if (!IsIndexable(entityType)) return; 

    var entityName = entityType.Name;   
    var entityIdName = string.Format("{0}Id", entityName); 

    var indexables = GetIndexableProperties(entityType); 

    Logger.Info(i => i("Populating the Full-text index with values from the {0} entity...", entityName)); 
    using (var analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30)) 
    using (var writer = new IndexWriter(FullTextDirectory.FullSearchDirectory, analyzer, IndexWriter.MaxFieldLength.UNLIMITED)) 
    { 
     foreach (var entity in entities) 
     { 
      var entityIdValue = entityType.GetProperty(entityIdName).GetValue(entity).ToString(); 
      var doc = CreateDocument(entity, entityIdName, entityIdValue, indexables); 
      writer.AddDocument(doc); 
     } 
    } 
    Logger.Info(i => i("Index population of {0} is complete.", entityName)); 
} 

这是给我agita方法:

public void RebuildIndices() 
{ 
    Logger.Info(i => i("Rebuilding the Full-Text indices...")); 
    var entityTypes = GetIndexableTypes(); 

    if (entityTypes.Count() == 0) return; 
    FullText.ClearIndices(); 
    foreach (var entityType in entityTypes) 
    { 
     FullText.PopulateIndex(
      _Session.CreateCriteria(entityType) 
      .List() 
      ); 
    } 
} 

看起来这将返回一个强类型List<T>但事实并非如此。我怎样才能得到这个强类型的列表,或者有没有其他更好的方法呢?

回答

1

如果你想得到强类型列表,你应该指定通用参数。我可以建议两个选项: 避免反射。我的意思是直接调用PopulateIndex每种类型:

public void RebuildIndexes() 
{ 
    Logger.Info(i => i("Rebuilding the Full-Text indices...")); 
    FullText.ClearIndices(); 
    FullText.PopulateIndex(LoadEntities<EntityA>()); 
    FullText.PopulateIndex(LoadEntities<EntityB>()); 
    ... 
} 

private IEnumerable<T> LoadEntities<T>() 
{ 
    _Session.QueryOver<T>().List(); 
} 

,也可以使用反射调用PopulateIndex:

public void RebuildIndices() 
{ 
    Logger.Info(i => i("Rebuilding the Full-Text indices...")); 
    var entityTypes = GetIndexableTypes(); 

    if (entityTypes.Count() == 0) return; 
    FullText.ClearIndices(); 
    foreach (var entityType in entityTypes) 
    { 
     var entityList = _Session.CreateCriteria(entityType).List(); 
     var populateIndexMethod = typeof(FullText).GetMethod("PopulateIndex", BindingFlags.Public | BindingFlags.Static); 
     var typedPopulateIndexMethod = populateIndexMethod.MakeGenericMethod(entityType); 
     typedPopulateIndexMethod.Invoke(null, new object[] { entityList }); 
    } 
} 
+0

什么是'elementMethod'在你的第二个例子吗? – 2013-03-02 16:01:24

+0

对不起,它必须是populateIndexMethod。修复。 – 2013-03-02 16:03:36

+0

entityList不会转换为“Invoke”方法所需的数组,Linq不支持无类型转换。 – 2013-03-02 16:07:55