[ http://issues.apache.org/jira/browse/IBATISNET-98?page=all ]
Ron Grabowski resolved IBATISNET-98:
------------------------------------
Resolution: Fixed
> Change implementation of IBatisNet.DataMapper.MappedStatements.RunQueryForMap
> so it works directly with the IDataReader and has support for
> DictionaryRowDelegate
> -----------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: IBATISNET-98
> URL: http://issues.apache.org/jira/browse/IBATISNET-98
> Project: iBatis for .NET
> Type: Improvement
> Versions: DataMapper 1.2.1
> Reporter: Ron Grabowski
> Assignee: Ron Grabowski
> Priority: Minor
>
> RunQueryForObject and RunQueryForList interact directly with an IDataReader
> object to populate the result object. RunQueryForMap does not. The current
> implementation calls ExecuteQueryForList then iterates through the returned
> IList to add the items to IDictionary object. The call to ExecuteQueryForList
> also involves calculating a cache key if caching is enabled. This is
> unnecessary becuase by the time RunQueryFor* methods are called, the check
> for the cache should have already taken place. At the very least the current
> implementation should call RunQueryForList internally to avoid the duplicate
> cache key calculation.
> A better implementation would be something similiar to the other RunQueryFor*
> methods:
> private IDictionary RunQueryForMap(SNIP)
> {
> IDictionary map = new Hashtable();
> using (IDbCommand command = _preparedCommand.Create(SNIP))
> {
> using (IDataReader reader = command.ExecuteReader())
> {
> while (reader.Read())
> {
> object obj = ApplyResultMap(request, reader, null);
> object key = ObjectProbe.GetPropertyValue(obj, keyProperty);
> object value = obj;
> if (valueProperty != null)
> {
> value = ObjectProbe.GetPropertyValue(obj, valueProperty);
> }
> map.Add(key, value);
> }
> }
> }
> return map;
> }
> That code only makes one iteration through the result set rather than placing
> everything into an IList then re-iterating through the IList.
> The above implementation could be improved to support a delegate to control
> how items are added to the IDictionary:
> // warning: changing name may break existing code...
> public delegate void ListRowDelegate(object item, IList list);
> // new!
> public delegate void DictionaryRowDelegate(object key, object value,
> IDictionary dictionary);
> ---
> // based off of RunQueryForList (this code works...I'm using it now)
> private IDictionary RunQueryForMap(SNIP)
> {
> IDictionary map = new Hashtable();
> using (IDbCommand command = _preparedCommand.Create(SNIP))
> {
> using (IDataReader reader = command.ExecuteReader())
> {
> if (dictionaryRowDelegate != null)
> {
> while (reader.Read() )
> {
> object obj = ApplyResultMap(request, reader, null);
> object key = ObjectProbe.GetPropertyValue(obj, keyProperty);
> object value = obj;
> if (valueProperty != null)
> {
> value = ObjectProbe.GetPropertyValue(obj, valueProperty);
> }
> map.Add(key, value);
> }
> else
> {
> while (reader.Read())
> {
> object obj = ApplyResultMap(request, reader, null);
> object key = ObjectProbe.GetPropertyValue(obj, keyProperty);
> object value = obj;
> if (valueProperty != null)
> {
> value = ObjectProbe.GetPropertyValue(obj, valueProperty);
> }
> dictionaryRowDelegate(key, value, map);
> }
> }
> }
> }
> }
> return map;
> }
> The new implementation should mimic ExecuteQueryForRowDelegate (i.e. bypass
> the cache for the time being). Fixing IBATISNET-87 should also fix the
> "broken" ExecuteQueryForDictionaryRowDelegate.
> Assuming we had a result set that contained the following data:
> UserId, PhoneNumber
> 1, 555-1212
> 1, 555-1414
> 1, 214-4757
> 2, 555-7894
> 3, 564-8975
> One could write a DictionaryRowDelegate that would associate user ids to
> phone numbers (i.e. a simple "groupBy"):
> private void userIdToPhoneNumbersDelegate(object key, object value,
> IDictionary dictionary)
> {
> int userId = (int)key;
> string phoneNumber = (string)value;
> ArrayList phoneNumbers = dictionary[userId] as ArrayList;
> if (phoneNumbers == null)
> {
> phoneNumbers = new ArrayList();
> }
> phoneNumbers.Add(phoneNumber);
> dictionary[userId] = phoneNumbers;
> }
> Output:
> ((IList)temp[1]).Count == 3
> ((IList)temp[2]).Count == 1
> ((IList)temp[3]).Count == 1
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira