在我的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<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;
这给了我我想要的东西:)
祝你好运
答案 0 :(得分:4)
您需要定义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并填充DataTable或数据集并将其返回。您可以在服务方法定义中更改任意数量的列。您甚至可以使用DataSet.GetXml()
将DataTable转换为Json
string json = JsonConvert.SerializeObject(table, Formatting.Indented);
答案 1 :(得分:3)
// 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
答案 2 :(得分:1)
SqlReader旨在使内存最小化,因此只会逐个查询结果。如果要获得所有结果,可以在代码周围使用while循环来获取行,只要它们可用即可。通过调用return,您将打破while循环并仅返回第一行。如果您要调用yield return,则您的方法将返回IEnumerable<string>
,而不是string
。
答案 3 :(得分:0)
您可以创建一个数组或List,并使用sqlReader填充List。 列表和数组可以使用WCF进行序列化和传输,也可以互操作。
在while循环中
listObject.Add(sqlReader[0].ToString());
答案 4 :(得分:0)
您需要实际读取所有datareader行,方法是将它们加载到数据表中,datareader是一个惰性加载对象,不能通过网络发送,因为它从未完全填充在那里:
DataTable dt=new DataTable();
dt.Load(dr);
然后,由于您使用的是wcf,因此可能需要将该数据表加载到与您的合同接口匹配的对象中。看看下面的snipet,它通过使用反射将任意数据表转换为匹配属性的行为良好的对象。
代码段用法
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;
}
}
}
答案 5 :(得分:0)
古老的线索,但我会加上我的两个:
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>>