如何在c# WCF中返回SqlDataReader
本文关键字:返回 SqlDataReader WCF | 更新日期: 2023-09-27 18:13:38
在我的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文件top:
List<ObjectNotification> objlist = new List<ObjectNotification>();
和
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;
这正是我想要的
您需要定义DataContract,如果您传递字符串列表或字符串数组,您的服务消费者需要知道哪个索引对应哪个列等。当您将来向服务添加或删除列时,这种方法将很难实现。你能做的是创建DataContract它拥有你需要发送的所有属性并相应地创建操作契约。现在,服务消费者可以在将来更新服务引用,以防更改字段而导致编译错误。这很容易识别。
public List<MyDataContract> GetData()
{
List<MyDataContract> list = new List<MyDataContract>();
//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<MyDataContract> GetData();
在我看来,我们需要更多通用的可重用代码…
如果你只有。net服务消费者,你可以从服务方法返回DaTaSet或DataTable。您需要具有SqlDataAdapter而不是sqlReader并填充数据表或数据集并返回它。您可以在不更改Service方法定义的情况下配置任意数量的列。您甚至可以通过使用DataSet.GetXml()
将数据表转换为Json
string json = JsonConvert.SerializeObject(table, Formatting.Indented);
// for instance
List<string> list = new List<string>();
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
SqlReader旨在将工作内存最小化,因此只会逐个查询结果。如果您想获得所有结果,可以在代码周围使用while循环来获取行,只要它们可用。通过调用return,您将中断while循环并只返回第一行。如果您调用yield return,则您的方法将返回IEnumerable<string>
而不是string
。
您可以创建一个数组或列表,并使用sqlReader填充列表。List和Array可以使用WCF序列化和传输,并且也是可互操作的。
在while循环内
listObject.Add(sqlReader[0].ToString());
您需要通过将所有数据读取器行加载到数据表中来实际读取它们,数据读取器是一个lazyload对象,由于它在开始时从未完全填充,因此无法通过网络发送:
DataTable dt=new DataTable();
dt.Load(dr);
然后,由于您正在使用wcf,您可能需要将该数据表加载到与您的契约接口匹配的对象中。看看下面的代码片段,它通过使用反射将任意数据表转换为行为良好的对象匹配属性。
使用 片段
List<myType> r = (List<myType>) dt.ToList<myType>();
片段
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
{
/// <summary>
/// Gets a list of objects based on a generic datatable
/// </summary>
/// <typeparam name="T">List of objects</typeparam>
/// <param name="table">Existing datatable</param>
/// <returns></returns>
public static IList<T> ToList<T>(this DataTable table) where T : new()
{
IList<PropertyInfo> properties = typeof(T).GetProperties().ToList();
IList<T> result = new List<T>();
foreach (var row in table.Rows)
{
var item = CreateItemFromRow<T>((DataRow)row, properties);
result.Add(item);
}
return result;
}
private static T CreateItemFromRow<T>(DataRow row, IList<PropertyInfo> 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;
}
/// <summary>
/// Creat a generic string list on the first field of a dataTable
/// </summary>
/// <param name="table"></param>
/// <returns></returns>
public static List<string> ToStringList(this DataTable table)
{
List<string> result = new List<string>();
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<List<string>> toReturn = new List<List<string>>();
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<string> innerList = new List<string>();
for (int i = 0; i < sqlReader.FieldCount; i++)
{
innerList.Add(sqlReader[i].ToString());
}
toReturn.Add(innerList);
}
con.Close();
}
}
}
}
那么你只需返回List<List<string>>