Silverlight 不支持Datatable 杯具

When you call DataSet.GetXml, the DataSet is turned into a string. It's no longer a DataSet. I say DataSet is difficult to be serialized by xml because the DataSet object itself is not marked as DataContract. You can't serialize a DataSet object. When you use DataSet.GetXml to return a string in your web service, the generated SOAP proxy class has no knowledge of the meaning of that string. On desktop .NET and .NET Compact Framework, you can use DataSet.ReadXml to construct a new DataSet object, and use it in Windows Forms and ASP.NET data binding scenarios. Windows Forms's data binding model has sophisticated supporting for binding to DataSet, especially for DataGridView. But Silverlight doesn't. IMO there're several reasons:

First, as you probably know, the desktop System.Data.dll assembly is more than 2 Mb. Even if we can cut off most features, it will still introduce a large increment on the size of runtime. As a browser plug-in, we have to keep the Silverlight runtime as small as possible.

Second, the data binding model in Silverlight is a subset of that in WPF, and is significantly different from Windows Forms and ASP.NET. In WPF, when you try to bind to a DataTable, we'll call its IListSource.GetList method to create an IList object, which is actually a DataView. Each member in the DataView is of type DataViewRow, which implements ICustomTypeDescriptor. ICustomTypeDescriptor is used to dynamically construct a type. But this interface is not in Silverlight yet. Even static reflection has limitations in Silverlight due to security concerns. So this model can't work in Silverlight. Also by dynamically constructing a type, performance will drop. See this blog post for more information.

Third, while I can't 100% assure you at this time, it's likely that we'll support ADO.NET Data Service (Astoria) in Beta2. Astoria is a special kind of WCF REST service. It does a good job for data driven applications. It's built on top of Entity Framework, and it'll expose the data as JSON or ATOM, and it's extensible. See this blog post for more information. Also we already support LINQ to XML, so you can easily create an object model from a generic REST service. With so many support for modern architectures, I don't see any values supporting DataSet will add. But anyway, you can continue ask for this feature. If enough people are asking for that, it's likely to be supported in VNext.

以上是在某论坛看到的原因 无非就是不便序列化,DLL太大不适合web,不符合json OR ATOM

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 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 该程序集中定义了一套DataSet、DataTa对象,作为数据通讯的数据格式,完全兼容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()); Silverlight与Wcf传递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中呢,就是Wcf将DataSet转成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、付费专栏及课程。

余额充值