On Thu, Jun 12, 2008 at 12:38 AM, Ron Grabowski <[EMAIL PROTECTED]> wrote:
> When QueryForList is called and there are no results an empty IList class > is returned. I think the same thing should happen when QueryForDataTable is > called and there aren't any results. An IList holds a list of items. A > DataTable holds a list of DataRows. QueryForDictionary always returns a > non-null object too. The convention when returning "container" classes in > .NET is that they're non-null and that the caller checks the appropriate > Count property to see if there are any items. +1 for returning an empty DataTable > If reader.Read() returns false the reader may still contain information > about the structure of the query (it does on SqlServer ). Perhaps the code > for initializing the DataTable can be refactored such that the Columns of > the DataTable are still created even if the there isn't any data. This would > be consistent with running a database query with "WHERE 1=0" ...you still > get a resultset and column information back even though the query didn't > return any rows. I'm pretty sure this is the behavior of > SqlDataAdapter.Fill(DataTable). To accomplish this, the code in > DataTableStrategy: -1 because in case of resulMap use, the resultMap is dynamically find against the DataReader if we have no value.... As with IList you can check dataTable.Rows.Count... > > // DataTableStrategy.Process > dataTable = new DataTable(resultMap.Id); > if (resultMap is AutoResultMap) > { > // snip - create columns calling GetSchemaTable > } > else > { > // snip - create columns from resultMap > } > > would need moved into MappedStatement.RunQueryForDataTable so a DataTable > instance is passed to resultStrategy.Process: > > // MappedStatment.RunQueryForDataTable > dataTable = new DataTable(resultMap.Id); > if (resultMap is AutoResultMap) > { > // snip - create columns calling GetSchemaTable > } > else > { > // snip - create columns from resultMap > } > > while (reader.Read()) > { > dataTable = (DataTable)resultStrategy.Process(request, ref reader, > dataTable); > } > > That would also be consistent with QueryForList and QueryForDictionary > because the List<> and Dictionary<> objects are created in MappedStatement. > > Going back to DataTableStrategy...when I was writing my DataSetDataMapper I > discovered that I didn't have to write my own DataTableStrategy; I just > relied on the fact that the resultStrategy object passed in automatically > returned items as object[] which is what the DataRow can use to populate > itself: > > DataRow dataRow = dataTable.NewRow(); > object result = resultStrategy.Process(request, ref reader, null); // > ObjectStrategy > if (result is object[]) > { > dataRow.ItemArray = (object[])result; > } > else > { > dataRow[0] = result; // seems to work ok! > } > dataTable.Rows.Add(dataRow); > > It almost seems like DataTableResultStrategy should be renamed > "DataRowResultStrategy" because its primary focus is on populating a single > DataRow. We're wanting to convert every row in reader into a DataRow; > > // MappedStatment.RunQueryForDataTable > dataTable = new DataTable(resultMap.Id); > if (resultMap is AutoResultMap) > { > // snip - create columns calling GetSchemaTable > } > else > { > // snip - create columns from resultMap > } > > while (reader.Read()) > { > DataRow dataRow = dataTable.NewRow(); > dataRow = (DataRow)dataRowResultStrategy.Process(request, ref reader, > dataRow); > dataTable.Rows.Add(dataRow); > } > > That's very similiar to what MappedStatement.RunQueryForList is doing. > RunQueryForList uses the resultStrategy to convert the reader into an object > then adds it to the list. +1 In SVN -- Cheers, Gilles Join my network on LinkedIn http://www.linkedin.com/in/sellig