简体   繁体   中英

WCF service returning DataSet

I have this WCF service:

public DataSet GetInfo()
{
        DataTable dt = new DataTable("Tbl");
        DataSet ds = new DataSet("Set");        
        OdbcCommand OdbcCmd;
        OdbcCmd = new OdbcCommand("select * FROM Products where id = 'JBE-235'", OdbcConn);          
        OdbcConn.Open();
        dt.Load(OdbcCmd.ExecuteReader());
        ds.Tables.Add(dt);           
        OdbcConn.Close();          
        return ds;
}

But I've read that returning a DataSet from a WCF service is a bad practice, I have a desktop application and I need to fill a DataGridView with the service's result.

private void ButtonInfo_Click(object sender, EventArgs e)
{ 
     WCFService service = new WCFService();
     DataGridView1.DataSource = service.GetInfo();
     service.Close();
}

What kind of data type should I get from the WCF service to fill the DataGridView correctly?

Thanks in advance.

The better way is to return DTO (in your case it will be collection of DTOs).

First, create DTO class that will contains expected fields from Products table. For example:

public class Product
{
    public string Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

Next, read values from database via DataReader :

// use IEnumerable<Product> for .net <= 4.0 and IReadOnlyCollection<Product> for .net >= 4.5
public IReadOnlyCollection<Product> GetInfo()
{
    OdbcCommand command = new OdbcCommand("select * FROM Products where id = 'JBE-235'", OdbcConn);          
    OdbcConn.Open();
    var reader = command.ExecuteReader();
    var products = new List<Product>();
    while (reader.Read())
    {
        var product = new Product();
        // reader index is the column name from query
        // You can also use column index, for example reader.GetString(0)
        product.Id = (string) reader["id"];
        product.Name = (string) reader["name"];
        product.Price = (decimal) reader["price"];
        products.Add(product);
    }
    return products;
}

Note that you need to close connection after reading all data, then the good practice is to use using statement to dispose it in the end of your method automatically. The other advice is to use command Parameters :

// use IEnumerable<Product> for .net <= 4.0 and IReadOnlyCollection<Product> for .net >= 4.5
public IReadOnlyCollection<Product> GetInfo()
{
    using(var con = GetConnection())
    {
        var cmd = new OdbcCommand("select * FROM Products where id = @Id", con);
        cmd.Parameters.AddWithValue("@Id", "JBE-235");
        con.Open();
        var reader = cmd.ExecuteReader();
        var products = new List<Product>();
        while (reader.Read())
        {
            products.Add(new Product { Id = (string) reader["id"], Name = (string) reader["name"], Price = (decimal) reader["price"] });
        }
        return products;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM