如何在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>