Silverlight传递DataTable终极解决方案

     目前实体类是我们采用的Silverlight与WCF传递数据的首选方法。但这种方法相对比较死,只能适用于业务逻辑比较简单的应用程序。对于那些在运行时才能知道具体数据的应用并不适合。相比之下传统的Aod.Net DataSet,DataTable具有很大的灵活性。但无奈在Silverlight端不被支持。


     网上已经有很多种通过特殊处理来变相实现Silverlight传递DataTable(DataSet)的文章。其中最典型的就是利用.Net Framework3.5的动态编译技术。前面查询建模系列中已经有所应用。但这种实现方法存在着严重的弊端就是动态编译过程相对较慢如果不进行缓存处理将极大的影响应用的性能。即使做了缓存处理当数据传递比较频繁时也会有性能降低的危险。而且就我在XCenter中的实现还存在着传递数据量的问题,由于XCenter中的DataSetData中的数据以List<List<object>>存储,数据在传递之前没有进行压缩处理。所以注定知能适合少量数据的传递。


     最近在网上看到一个加拿大的网站公开了一个类库。很好的解决Silverlight传递DataTable的难题。大概的思路就是在Silverlight端实现了一套类似Ado.Net DataSet,DataTable的API并且通过Xml传递数据。更可贵的是自动提供了对Xml的压缩功能(他的压缩实现基于对所传递的xml数据的简化)。如果这种压缩还不能达到我们对大数据量传递的要求。我们可以应用第三方Silverlight压缩组件进一步进行压缩并传递。这样的类库在CodePlex上很多。


  官方网站http://silverlightdataset.net/silverlightdataset/Default.aspx 
  有喜爱并了解的朋友可以和我交流。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.概述 该组件提供类似ADO.NET编程接口,可以直接在Silverlight端访问Web端数据库。可以实现在Web端无需事先手工编写或自动创建任何程序代码和数据实体类的情况下, 便可在Silverlight端对Web端数据库进行增加、删除、修改、查询等数据操作。此外, 还支持访问数据库的存储过程(StoredProcdures)、视图(Views)、自定义函数(User Defined Functions)等。 2、使用前的准备 2.1组件Lib文件 该组件包含3个文件: System.Data.Silverlight.dll、 System.Data.Silverlight.Web.dll DataHandler.ashx 2.1.1System.Data.Silverlight.dll Silverlight端需引用的程序集,引用该程序集还需要引用关联的程序集,包含: System.ComponentModel.DataAnnotations.dll System.Windows.Controls.Data.dll System.Windows.Controls.Data.Input.dll System.Windows.Data.dll System.Xml.Linq.dll 该程序集中定义了一套DataSetDataTa对象,作为数据通讯的数据格式,完全兼容ADO.NET中的DataSetDataTable,两者之间可以通过XML互相转换,提供相应的转换方法。程序中还定义了一套DbConnection、DbCommand对象,用于向Web端发起数据库操作命令,使用方式类似ADO.NET。 2.1.2 System.Data.Silverlight.Web.dll Web服务器端文件,需要把该程序集拷贝到网站Bin目录,无需引用。 2.1.3 DataHandler.ashx Web服务器端的文件,需要把该文件拷贝到网站根目录。 2.2同步方式操作数据库示例 //创建一个数据连接 DbConnection conn = new DbConnection("Server=192.168.0.7;DataBase=JitonClient;Uid=sa;Pwd=jiton;"); //创建一个数据命令 DbCommandSyn cmd = new DbCommandSyn(); //设置命令的连接 cmd.Connection = conn; //设置SQL语句,可以是存储过程 cmd.CommandText = "SELECT [UserId],[UserName],[GroupId] FROM [Usertb] WHERE [GroupId]=@GroupId"; //设置命令类型,一般SQL语句是Text,存储过程是StoredProcedure cmd.CommandType = DbCommandType.Text; //设置执行类型 cmd.ExecuteType = DbExecuteType.Reader; //添加一个参数,无参数可以不添加 cmd.Parameters.Add(new DbParameter(DbType.Int32, "@GroupId", 5)); //执行命令,得到结果 DbCommandExecuteResult result = cmd.Execute(); if (!string.IsNullOrEmpty(result.ErrMsg))//首先判断ErrMsg是否有值,有表示执行过程发生错误 { MessageBox.Show("发生错误:" + result.ErrMsg); } else { DataTable dt = result.ReaderResult; //将数据显示在DataGrid中 this.dataGrid1.ItemsSource = dt.Rows; } 2.3异步方式操作数据库示例 //创建一个数据连接 DbConnection conn = new DbConnection("Data Source=|DataDirectory|CSmsPlatThird.db;Pooling=true;FailIfMissing=false"); //设置使用的数据访问程序集 conn.AssemblyName = "System.Data.SQLite"; //设置数据工厂,这里是SQLite的数据工厂 conn.DbProviderFactory = "System.Data.SQLite.SQLiteFactory"; //创建一个数据命令 DbCommandAsyn cmd = new DbCommandAsyn(); //设置命令的连接 cmd.Connection = conn; //设置SQL语句,可以是存储过程 cmd.CommandText = "SELECT [Id],[Content],[PlatFlag],[DateTime] FROM [T_Logger] WHERE [Id]>=@Id"; //设置命令类型,一般SQL语句是Text,存储过程是StoredProcedure cmd.CommandType = DbCommandType.Text; //设置执行类型 cmd.ExecuteType = DbExecuteType.Reader; //添加一个参数,无参数可以不添加 cmd.Parameters.Add(new DbParameter(DbType.Int32, "@Id", 3)); //设置命令执行完毕的委托事件 cmd.ExecuteEnd += new EventHandler<DbCommandExecuteResult>(cmd_ExecuteEnd); //异步执行命令 cmd.Execute(); void cmd_ExecuteEnd(object sender, DbCommandExecuteResult e) { if (!string.IsNullOrEmpty(e.ErrMsg))//首先判断ErrMsg是否有值,有表示执行过程发生错误 { MessageBox.Show("发生错误:" + e.ErrMsg); } else { DataTable dt = e.ReaderResult; //将数据显示在DataGrid中 this.dataGrid1.ItemsSource = dt.Rows; } } 2.4对其它数据库的支持 该组件默认支持SQL Sserver,理论上也可支持其它数据库,只要数据库提供对应的ADO.NET实现接口,已经测试过Access、SQLite。操作其它数据库时必须把对应的ADO.NET实现接口的程序集拷贝到网站Bin目录下面,操作SQL Server无需该步骤。比如操作SQLite数据库,需要把SQLite的ADO.NET实现接口程序集System.Data.SQLite.dll文件拷贝到网站Bin下面。此外还需指定DbConnection对象的AssemblyName、DbProviderFactory属性的值。 //创建一个数据连接 DbConnection conn = new DbConnection("Data Source=|DataDirectory|CSmsPlatThird.db;Pooling=true;FailIfMissing=false"); //设置使用的数据访问程序集 conn.AssemblyName = "System.Data.SQLite"; //设置数据工厂,这里是SQLite的数据工厂 conn.DbProviderFactory = "System.Data.SQLite.SQLiteFactory"; 其它操作步骤和操作SQL Server无差异,完整的示例代码见2.3中的示例。 2.5技术交流 有任何问题可以加入唯一指定的专用QQ群153079750进行反馈交流,也欢迎加入笔者的另一个Silverlight技术群175213051进行交流。
需要下载:Silverlight.DataSetSilverlight.DataSetConnector 下面是示例: DataTable Dt = new DataTable(); DataColumn col1 = new DataColumn("CompanyName"); Dt.Columns.Add(col1); DataColumn col2 = new DataColumn("Email"); Dt.Columns.Add(col2); DataRow Row = Dt.NewRow(); Row[0] = "杭州市公司"; Row[1] = "TEL110"; Dt.Rows.Add(Row); grid1.DataContext = Dt.GetBindableData(new Connector()); SilverlightWcf传递DataTable(以下均指我们下载这个程序集中的DataTable) 由于Silverlight这个程序集中使用的System.dll是C:\Program Files\Reference Assemblies\Microsoft\Framework\Silverlight\v3.0\System.dll(2.0.5.0版本)而不是.net framework中的那个System.dll(2.0.0.0.0版本),所以在Wcf中不能直接使用DataTable,那么如何将DataTable信息从Wcf传递Silverlight中呢,就是WcfDataSet转成string或byte[]传递Silverlight然后再将其还原成DataSet,看下面的代码示列: Wcf端: public string GetRecordset(string QuerySql) { DataTable Dt = DbAgent.GetRecordset(QuerySql); DataSet ds = new DataSet(); ds.Tables.Add(Dt); return Silverlight.DataSetConnector.Connector.ToXml(ds); } Silverlight端: void client_GetRecordsetCompleted(object sender, SilverlightApplication1.DbServer.GetRecordsetCompletedEventArgs e) { if (e.Error != null) { MessageBox.Show(e.Error.Message + e.Error.StackTrace); } else { DataSet ds = new DataSet(); ds.FromXml(e.Result); DataContext = ds.Tables[0].GetBindableData(new Connector()); } } 此DataTable中存入的数据不是object类型的,而全是string类型的,如果数据库中存的值为null,那么取出来的值是null而不是DbNull.Value.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值