2013-03-02 110 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