You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user-cs@ibatis.apache.org by Ron Grabowski <ro...@yahoo.com> on 2009/02/15 21:01:09 UTC

QueryWithRowDelegateDictionaryCreator to help with bulk loading one-to-many relationships

Using the RowDelegate approach avoids having to iterate through the returned IList<T> a second time to do the grouping:

public class QueryWithRowDelegateDictionaryCreator<TKey, T>
{
    private readonly Func<T, TKey> keySelector;

    private readonly IDictionary<TKey, IList<T>> dictionary = new Dictionary<TKey, IList<T>>();

    public QueryWithRowDelegateDictionaryCreator(Func<T, TKey> keySelector)
    {
        this.keySelector = keySelector;
    }

    public void RowDelegate<TUnused>(object obj, object parameterObject, IList<TUnused> unused)
    {
        T item = (T)obj;
        TKey key = keySelector(item);

        IList<T> list;
        if (dictionary.TryGetValue(key, out list) == false)
        {
            list = new List<T>();
            dictionary[key] = list;
        }
        list.Add(item);
    }

    public IDictionary<TKey, IList<T>> Dictionary
    {
        get { return dictionary; }
    }
}

public CategorySqlMapDao : ICategoryDao
{
 private ISqlMapper sqlMapper;

 public CategorySqlMapDao(ISqlMapper sqlMapper)
 {
  this.sqlMapper = sqlMapper;
 }

 public IList<Product> FindProducts(int categoryId)
 {
  return sqlMapper.QueryForList("FindProductsCategoryId", categoryId);
 }

 public IDictionary<int, IList<Product> FindProducts(int[] categoryIds)
 {
  var dictionaryCreator = new QueryWithRowDelegateDictionaryCreator<int, Product>(p => p.CategoryId);
  sqlMapper.QueryWithRowDelegate("FindProductsCategoryIds", categoryIds, dictionaryCreator.RowDelegate);
  return dictionaryCreator.Dictionary;  
 }
}