Silverlight and WCF (WebService) interactions are more data-transitive in the form of entity classes. However, the form is not available for the report platform because you cannot predict which fields of which database the customer is selecting when designing the report. So tradition. NET is a good solution. The following is a discussion of the author's solution. You are welcome to pat Bricks.
The idea of the whole solution is to divide the DataTable into metadata (MetaData) and data. Metadata Needless to say is the column information of the current DataTable (for example, column name, data type, maximum length, etc.). As for data, we know that a DataTable is a two-dimensional structure. So I choose to list<list<object>> the form of data storage. This kind of data structure is not efficient, but scalability is relatively strong to the client for further data processing (for example: Subtotal, dynamic columns, etc.). After Metadata,data is passed to the client, client code dynamically creates entity classes based on MetaData information with TypeBuilder APIs, and converts them to list<object> bound to the DataGrid.
First, define the data structure, where I use Datasetdata as a custom container class.
Field.cs field information (corresponding to columns in a DataTable)
Field
/**////<summary>
Field information
</summary>
[Xcenter.framework.public.serialization.serializable,datacontract]
public class Field:xcenter.framework.public.core.icloneable,imobileobject
{
Public Field ()
{
}
Props#region Props
private string DataType;
private string caption;
private string FieldName;
private string Note;
private string expression;
private int precision;
private int scale;
private int maxLength;
private bool Isrequire;
private bool IsKey;
private bool IsReadOnly;
/**////<summary>
Data type
</summary>
[DataMember]
public string DataType
{
get {return dataType;}
set {DataType = value;}
}
/**////<summary>
Display Name
</summary>
[DataMember]
public string Caption
{
get {return caption;}
Set {caption = value;}
}
/**////<summary>
Field name
</summary>
[DataMember]
public string Filedname
{
get {return fieldName;}
set {fieldName = value;}
}
/**////<summary>
An expression
</summary>
[DataMember]
public string Expression
{
get {return expression;}
set {expression = value;}
}
/**////<summary>
Data length
</summary>
[DataMember]
public int Precision
//{
get {return precision;}
set {precision = value;}
//}
/**////<summary>
Number of decimal places
</summary>
[DataMember]
public int Scale
//{
get {return scale;}
set {scale = value;}
//}
/**////<summary>
Note
</summary>
[DataMember]
public string Note
//{
get {return note;}
set {note = value;}
//}
/**////<summary>
Maximum length
</summary>
[DataMember]
public int MaxLength
{
get {return maxLength;}
set {maxLength = value;}
}
/**////<summary>
Is nullable
</summary>
[DataMember]
public bool Isrequire
{
get {return isrequire;}
set {Isrequire = value;}
}
/**////<summary>
Whether the primary key
</summary>
[DataMember]
public bool IsKey
{
get {return iskey;}
set {IsKey = value;}
}
/**////<summary>
is read-only
</summary>
[DataMember]
public bool IsReadOnly
{
get {return isreadonly;}
set {isreadonly = value;}
}
#endregion
public override string ToString ()
{
return String.IsNullOrEmpty (caption)? Fieldname:caption;
}
public override bool Equals (object obj)
{
if (FieldName = null | | obj = NULL | |!) ( obj is Field)
return false;
Field F = (field) obj;
Return F.filedname.equals (FieldName);
}
public override int GetHashCode ()
{
return Fieldname.gethashcode ();
}