如何在C#WCF中返回SqlDataReader?
在我的C#WCF服务中,我有一个SqlDataReader
,它包含我想要返回给客户端的数据行。
如何返回SqlDataReader
所有内容?
现在我有
if (sqlReader != null) { if (sqlReader.HasRows) { while (sqlReader.Read()) { return sqlReader[0].ToString(); } sqlConn.Close(); } else { return null; } }
这只会返回第一个结果。 该类的返回类型目前是字符串。 我在想数组中的数组,但我不确定如何?
编辑:
感谢您的回复。 我有兴趣返回服务“创建”的整个SQL数据。 不在线第一列([0]) – 这仅用于测试。
但我不知道如何从服务回到客户端。
- 如何退货?
例如。 在Powershell中我会创建一个集合并向该集合添加对象,如果我必须在客户端之间传递它。
我在C#和WCF中寻找类似的东西。
非常感谢到目前为止:)
编辑#2:
得到它了! 🙂
创建了一个新类(例如):
public class ObjectNotification { public string AlertDescription; public string Servername; }
在我的svc.cs文件中:
List objlist = new List();
和
if (sqlReader.HasRows) { while (sqlReader.Read()) { ObjectNotification obj = new ObjectNotification(); obj.AlertDescription = sqlReader["AlertDescription"].ToString(); obj.Servername = sqlReader["ComputerName"].ToString(); objlist.Add(obj); } } return objlist;
这给了我我想要的:)
最好的祝福
// for instance List list = new List (); if (sqlReader != null) { if (sqlReader.HasRows) { while (sqlReader.Read()) { //return sqlReader[0].ToString(); list.Add(sqlReader[0].ToString()); } sqlConn.Close(); } else { return null; } } return list; // ta-da
您需要定义DataContract,如果您传递字符串列表或字符串数组,您的服务使用者需要知道哪个索引是哪个列等等。当您将来向服务添加或删除列时,这种方法将很难。 您可以做的是创建DataContract,它具有您需要发送的所有属性并相应地创建操作合同。 现在服务消费者可以在将来更新服务引用,如果更改字段,他们将收到编译器错误。 这很容易识别。
public List GetData() { List list = new List (); //your code if (sqlReader != null) { if (sqlReader.HasRows) { while (sqlReader.Read()) { list.Add(new MyDataContract() { Id = (int)sqlReader["Id"].ToString(), Name= sqlReader = sqlReader["Name"].ToString() }); } sqlConn.Close(); } } //finally return list of data return list; }
样本数据合同
[DataContract] public class MyDataContract { [DataMember] public int Id{ get; set; } [DataMember] public string Name{ get; set; } }
和经营合同
[OperationContract] List GetData();
在我看来,我们需要更通用的可重用代码……
如果您只有.net服务使用者,则可以从服务方法返回DaTaSet或DataTable 。 您需要使用SqlDataAdapter而不是sqlReader并填充DataTable或数据集并将其返回。 您可以在服务方法定义中更改任意数量的列。 您甚至可以使用DataSet.GetXml()
将返回类型作为字符串发送
将DataTable转换为Json
string json = JsonConvert.SerializeObject(table, Formatting.Indented);
SqlReader旨在使内存最小化,因此只能逐个查询结果。 如果您想获得所有结果,只要它们可用,您就可以在代码周围使用while循环来获取行。 通过调用return,您将打破while循环并仅返回第一行。 如果你要调用yield return,你的方法将返回IEnumerable
而不是string
。
您可以创建一个数组或List,并使用sqlReader填充List。 List和Array可以使用WCF进行序列化和传输,也可以互操作。
在while循环中
listObject.Add(sqlReader[0].ToString());
您需要通过将所有datareader行加载到数据表中来实际读取所有datareader行,而datareader是一个惰性对象,并且无法通过网络发送,因为它从未完全填充在起始位置:
DataTable dt=new DataTable(); dt.Load(dr);
然后,由于您使用的是wcf,您可能需要将该数据表加载到与您的合同接口匹配的对象中。 看看下面的snipet,它通过使用reflection将任意数据表转换为匹配属性的表现良好的对象。
代码段使用情况
List r = (List ) dt.ToList ();
片段
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using System.Reflection; namespace xxxx.Sql.Extensions { public static class DataTableExtensions { /// /// Gets a list of objects based on a generic datatable /// /// List of objects /// Existing datatable /// public static IList ToList (this DataTable table) where T : new() { IList properties = typeof(T).GetProperties().ToList(); IList result = new List (); foreach (var row in table.Rows) { var item = CreateItemFromRow ((DataRow)row, properties); result.Add(item); } return result; } private static T CreateItemFromRow (DataRow row, IList properties) where T : new() { T item = new T(); foreach (var property in properties) { if (row.Table.Columns.Contains(property.Name)) { var prop = row[property.Name] == System.DBNull.Value ? null : row[property.Name]; property.SetValue(item, prop, null); } } return item; } /// /// Creat a generic string list on the first field of a dataTable /// /// /// public static List ToStringList(this DataTable table) { List result = new List (); foreach (DataRow dr in table.Rows) result.Add(dr[0].ToString()); return result; } } }
古老的线索,但我会加上我的两个:
string sqltext = @"select a.columnown, a.columntwo, a.columnthreee from blahblah as a"; List> toReturn = new List>(); using (SqlConnection con = new SqlConnection("YourConnectionString")) { con.Open(); SqlCommand cmd = con.CreateCommand(); cmd.CommandText = sqlTest; using (SqlDataReader sqlReader = cmd.ExecuteReader()) { if (sqlReader != null) { if (sqlReader.HasRows) { while (sqlReader.Read()) { List innerList = new List (); for (int i = 0; i < sqlReader.FieldCount; i++) { innerList.Add(sqlReader[i].ToString()); } toReturn.Add(innerList); } con.Close(); } } } }
那么你只需返回List
>