【问题标题】:LINQ query against GridView filled with SqlDataSource针对填充有 SqlDataSource 的 GridView 的 LINQ 查询
【发布时间】:2010-02-11 12:08:41
【问题描述】:

我需要对填充有SqlDataSourceGridView 进行LINQ 查询 - 以从行创建字典。

所以我有:

<asp:GridView runat="server" ID="gridCurrency" DataSourceID="sourceCurrency" OnDataBound="gridCurrency_DataBound"
<asp:SqlDataSource runat="server" ID="sourceCurrency" ConnectionString="<%$ ConnectionStrings:MyConnStr %>" SelectCommand="[getCurrencies]" SelectCommandType="StoredProcedure" />

protected void gridCurrency_DataBound(object sender, EventArgs e)
{
    var dic = (from row in ((DataView)sourceCurrency.Select(DataSourceSelectArguments.Empty)).Table.AsEnumerable()
              select new
              {
                  ID = (byte)row["ID"],
                  CurrencyName = (string)row["name"]
              }).ToDictionary(k => k.ID, k => k.CurrencyName);
}

在没有GridView.DataSouce 的情况下,有没有比我更好的方法从GridView 获得DataTable

【问题讨论】:

  • 我不再使用 SqlDataSource,但是当我使用的时候,我需要在我的代码隐藏中获取一个 DataTable,我就是这样做的。
  • @Byron Sommardahl:谢谢!你现在用什么?
  • 好吧,为了获得更多控制权并正确测试,我将服务器控件从代码隐藏绑定到数据集。我将通过示例发布答案。

标签: .net asp.net linq gridview


【解决方案1】:

我更喜欢在我的代码隐藏中绑定我的服务器控件。我可以更好地调试和测试它。我也不必做其他疯狂的事情来从代码隐藏中获取我的绑定数据......它已经存在了。这是一个例子。

假设 SQL 中的存储过程如下:

CREATE PROCEDURE selEmployees
@DeptId int,
@SearchString varchar(100)
AS
BEGIN
SELECT TOP 1000 * FROM Employees 
WHERE DeptId = @DeptId AND CONTAINS(*, SearchString);   
END

我可以将该存储过程与我的实体类或页面代码隐藏中的方法进行匹配,如下所示:

public static DataSet selEmployees(int DeptId, string SearchString)
    {
        DataSet ds = new DataSet();
        SqlConnection con = new SqlConnection(clsData.getConnString());
        SqlCommand cmd = new SqlCommand("selEmployees", con); // stored proc name
        cmd.CommandType = CommandType.StoredProcedure;
        SqlParameter _DeptId = cmd.Parameters.Add("@DeptId", SqlDbType.Int); //stored proc parameter name and datatype
        _DeptId.Value = DeptId; //assign method parameter value to sql parameter
        SqlParameter _SearchString = cmd.Parameters.Add("@SearchString", SqlDbType.Int); //stored proc parameter name and datatype
        _SearchString.Value = SearchString; //assign method parameter value to sql parameter
        SqlDataAdapter adapt = new SqlDataAdapter(cmd);
        adapt.SelectCommand = cmd;
        con.Open();
        try
        {
            adapt.Fill(ds);
        }
        catch (Exception ex)
        {
            string msg = ex.ToString();
        }
        finally
        {
            con.Close();
            con.Dispose();
        }
        return ds;
    }

然后,我可以像这样在 page_load 将我的数据绑定到我的服务器控件:

protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            GridView1.DataSource = Employees.selEmployees(MyDeptId, MySearchString);
            GridView1.DataBind();
        }
    }

如果您尝试这样做,请务必从标记中的 GridView 中删除 DataSourceId 参数。 DataSource 和 DataSourceId 不能一起玩。

注意:实际上有一百万种更好的方法可以做到这一点。这篇文章的目的是说明在标记中使用 SqlDataSource 的一种简单替代方法。

更进一步的一种方法是将生成的数据集分配给可重用的变量,例如页面属性:

public partial class ViewEmployees : System.Web.UI.Page
{
    public DataSet DataSetEmployees { get; set; } //re-usable property gets set at page_load

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            //save the dataset to a re-usable property
            DataSetEmployees = Employees.selEmployees(MyDeptId, MySearchString);

            //bind using the property
            GridView1.DataSource = DataSetEmployees;
            GridView1.DataBind();
        }
    }
}

通过这个简单的升级,您可以在整个页面中使用和重复使用 DataSet,而无需重新查询数据库。

【讨论】:

  • @Byron Sommardahl:非常感谢!很有意思。而且新鲜。你能推荐下一步吗?我的意思是你说“实际上有一百万种更好的方法可以做到这一点”。
  • 我觉得下一步是在你的思维中变得更加面向对象。在我自己的进步中,我已经从仅仅使用数据集转向使用通用列表和对象。因此,我有一个强类型的客户对象列表,而不是一组客户行。
  • 朝着这个方向前进的一种方法是尝试 Linq to SQL 类(google that)。一旦掌握了这一点,您就可以继续使用实体框架(或当时“流行”的任何东西)。有人可能有更好的建议。
猜你喜欢
  • 1970-01-01
  • 2016-03-03
  • 2016-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多