This commit is contained in:
@@ -0,0 +1,376 @@
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
//using CSLA.Resources;
|
||||
|
||||
namespace GZTW.AyaNova.BLL
|
||||
{
|
||||
#pragma warning disable 1591
|
||||
|
||||
/// <summary>
|
||||
/// An ReportDataSetAdapter is used to convert data in an object
|
||||
/// or collection into a ReportDataSet suitable for using with AyaNova reporting
|
||||
/// methods.
|
||||
/// </summary>
|
||||
public class ReportDataSetAdapter
|
||||
{
|
||||
ArrayList _columns = new ArrayList();
|
||||
|
||||
public struct ColumnInfo
|
||||
{
|
||||
internal string name;
|
||||
internal System.Type type;
|
||||
|
||||
public string ColumnName
|
||||
{
|
||||
get
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
public System.Type ColumnType
|
||||
{
|
||||
get { return type; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given a data source
|
||||
/// returns an arraylist containing
|
||||
/// ColumnInfo structures
|
||||
/// for each column found
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <returns></returns>
|
||||
public ArrayList GetDataSourceColumns(object source)
|
||||
{
|
||||
AutoDiscover(source);
|
||||
return _columns;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fills the DataSet with data from an object or collection.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The name of the DataTable being filled is will be the class name of
|
||||
/// the object acting as the data source. The
|
||||
/// DataTable will be inserted if it doesn't already exist in the DataSet.
|
||||
/// </remarks>
|
||||
/// <param name="ds">A reference to the DataSet to be filled.</param>
|
||||
/// <param name="source">A reference to the object or collection acting as a data source.</param>
|
||||
public void Fill(ReportDataSet ds, object source)
|
||||
{
|
||||
string className = source.GetType().Name;
|
||||
|
||||
Fill(ds, className, source);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fills the DataSet with data from an object or collection.
|
||||
/// (internally used by AyaNova for reporting compatibility with DevExpress report designer component)
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The name of the DataTable being filled is specified as a parameter. The
|
||||
/// DataTable will be inserted if it doesn't already exist in the DataSet.
|
||||
/// </remarks>
|
||||
/// <param name="ds">A reference to the DataSet to be filled.</param>
|
||||
/// <param name="tableName"></param>
|
||||
/// <param name="source">A reference to the object or collection acting as a data source.</param>
|
||||
public void Fill(ReportDataSet ds, string tableName, object source)
|
||||
{
|
||||
DataTable dt = ds.Tables[tableName];
|
||||
bool exists = (dt != null);
|
||||
|
||||
if(!exists)
|
||||
dt = new DataTable(tableName);
|
||||
|
||||
Fill(dt, source);
|
||||
|
||||
if(!exists)
|
||||
ds.Tables.Add(dt);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fills a DataTable with data values from an object or collection.
|
||||
/// </summary>
|
||||
/// <param name="dt">A reference to the DataTable to be filled.</param>
|
||||
/// <param name="source">A reference to the object or collection acting as a data source.</param>
|
||||
public void Fill(DataTable dt, object source)
|
||||
{
|
||||
AutoDiscover(source);
|
||||
DataCopy(dt, source);
|
||||
}
|
||||
|
||||
#region Data Copy
|
||||
|
||||
void DataCopy(DataTable dt, object source)
|
||||
{
|
||||
if(source == null) return;
|
||||
if(_columns.Count < 1) return;
|
||||
|
||||
if(source is IListSource)
|
||||
{
|
||||
DataCopyIList(dt, ((IListSource)source).GetList());
|
||||
}
|
||||
else
|
||||
{
|
||||
if(source is IList)
|
||||
{
|
||||
DataCopyIList(dt, (IList)source);
|
||||
}
|
||||
else
|
||||
{
|
||||
// they gave us a regular object - create a list
|
||||
ArrayList col = new ArrayList();
|
||||
col.Add(source);
|
||||
DataCopyIList(dt, (IList)col);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DataCopyIList(DataTable dt, IList ds)
|
||||
{
|
||||
// create columns if needed
|
||||
foreach(ColumnInfo column in _columns)
|
||||
{
|
||||
if(!dt.Columns.Contains(column.name))
|
||||
dt.Columns.Add(column.name,column.type);
|
||||
}
|
||||
|
||||
// load the data into the control
|
||||
dt.BeginLoadData();
|
||||
for(int index = 0; index < ds.Count; index++)
|
||||
{
|
||||
DataRow dr = dt.NewRow();
|
||||
foreach(ColumnInfo column in _columns)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
dr[column.name] = GetField(ds[index], column.name);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
dr[column.name] = ex.Message;
|
||||
}
|
||||
}
|
||||
dt.Rows.Add(dr);
|
||||
}
|
||||
dt.EndLoadData();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region AutoDiscover
|
||||
|
||||
void AutoDiscover(object source)
|
||||
{
|
||||
object innerSource;
|
||||
|
||||
if(source is IListSource)
|
||||
{
|
||||
innerSource = ((IListSource)source).GetList();
|
||||
}
|
||||
else
|
||||
{
|
||||
innerSource = source;
|
||||
}
|
||||
|
||||
_columns.Clear();
|
||||
|
||||
if(innerSource is DataView)
|
||||
{
|
||||
ScanDataView((DataView)innerSource);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(innerSource is IList)
|
||||
{
|
||||
ScanIList((IList)innerSource);
|
||||
}
|
||||
else
|
||||
{
|
||||
// they gave us a regular object
|
||||
ScanObject(innerSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScanDataView(DataView ds)
|
||||
{
|
||||
for(int field = 0; field < ds.Table.Columns.Count; field++)
|
||||
{
|
||||
ColumnInfo i=new ColumnInfo();
|
||||
i.name=ds.Table.Columns[field].ColumnName;
|
||||
i.type=ds.Table.Columns[field].DataType;
|
||||
_columns.Add(i);
|
||||
}
|
||||
}
|
||||
|
||||
void ScanIList(IList ds)
|
||||
{
|
||||
if(ds.Count > 0)
|
||||
{
|
||||
// retrieve the first item from the list
|
||||
object obj = ds[0];
|
||||
|
||||
if(obj is ValueType && obj.GetType().IsPrimitive)
|
||||
{
|
||||
// the value is a primitive value type
|
||||
ColumnInfo i=new ColumnInfo();
|
||||
i.name="Value";
|
||||
i.type=obj.GetType();
|
||||
_columns.Add(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(obj is string)
|
||||
{
|
||||
// the value is a simple string
|
||||
ColumnInfo i=new ColumnInfo();
|
||||
i.name="Text";
|
||||
i.type=typeof(string);
|
||||
_columns.Add(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have a complex Structure or object
|
||||
ScanObject(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScanObject(object source)
|
||||
{
|
||||
Type sourceType = source.GetType();
|
||||
|
||||
// retrieve a list of all public properties
|
||||
PropertyInfo [] props = sourceType.GetProperties();
|
||||
for(int column = 0; column < props.Length; column++)
|
||||
if(props[column].CanRead)
|
||||
{
|
||||
ColumnInfo i=new ColumnInfo();
|
||||
i.name=props[column].Name;
|
||||
if(props[column].PropertyType ==typeof(decimal))
|
||||
i.type=props[column].PropertyType;
|
||||
else
|
||||
i.type=typeof(object);
|
||||
_columns.Add(i);
|
||||
}
|
||||
|
||||
// retrieve a list of all public fields
|
||||
FieldInfo [] fields = sourceType.GetFields();
|
||||
for(int column = 0; column < fields.Length; column++)
|
||||
{
|
||||
ColumnInfo i=new ColumnInfo();
|
||||
i.name=fields[column].Name;
|
||||
i.type=fields[column].FieldType;
|
||||
_columns.Add(i);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetField
|
||||
//case 1346 was string but needs to be object to support images
|
||||
object GetField(object obj, string fieldName)
|
||||
{
|
||||
|
||||
if(obj is DataRowView)
|
||||
{
|
||||
// this is a DataRowView from a DataView
|
||||
return ((DataRowView)obj)[fieldName].ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(obj is ValueType && obj.GetType().IsPrimitive)
|
||||
{
|
||||
// this is a primitive value type
|
||||
if(obj == null)
|
||||
return string.Empty;
|
||||
else
|
||||
return obj.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(obj is string)
|
||||
{
|
||||
// this is a simple string
|
||||
if(obj == null)
|
||||
return string.Empty;
|
||||
else
|
||||
return obj.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
// this is an object or Structure
|
||||
try
|
||||
{
|
||||
Type sourcetype = obj.GetType();
|
||||
|
||||
// see if the field is a property
|
||||
PropertyInfo prop = sourcetype.GetProperty(fieldName);
|
||||
|
||||
if(prop == null || !prop.CanRead)
|
||||
{
|
||||
// no readable property of that name exists - check for a field
|
||||
FieldInfo field = sourcetype.GetField(fieldName);
|
||||
|
||||
if(field == null)
|
||||
{
|
||||
// no field exists either, throw an exception
|
||||
throw new System.Data.DataException(
|
||||
"NoSuchValueExistsException" + fieldName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// got a field, return its value
|
||||
return field.GetValue(obj).ToString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// found a property, return its value
|
||||
|
||||
//case 1346 image fields can't be returned as string
|
||||
//so return without conversion to string
|
||||
Type ttt = prop.PropertyType;
|
||||
|
||||
//case 1632
|
||||
if (ttt.IsEnum)
|
||||
{
|
||||
//convert to localized text value
|
||||
System.Enum en=prop.GetValue(obj, null) as System.Enum;
|
||||
string s= EnumDescConverter.GetEnumDescription(en);
|
||||
return s;
|
||||
}
|
||||
|
||||
//case 1346
|
||||
if (ttt == typeof(byte[]) || ttt == typeof(System.Drawing.Bitmap))
|
||||
{
|
||||
return prop.GetValue(obj, null);
|
||||
}
|
||||
|
||||
return prop.GetValue(obj, null).ToString();
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
throw new System.Data.DataException(
|
||||
"ErrorReadingValueException" + fieldName, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
#pragma warning restore 1591
|
||||
}
|
||||
Reference in New Issue
Block a user