2010-02-11 7 views
0

Je dois faire une requête LINQ contre GridView rempli avec SqlDataSource - pour créer un dictionnaire à partir de lignes.requête LINQ contre GridView rempli avec SqlDataSource

J'ai donc:

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

et

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); 
} 

Y at-il une meilleure façon puis mon pour obtenir un DataTable de GridView alors qu'aucun GridView.DataSouce est présent.

+1

Je n'utilise plus SqlDataSource, mais à l'époque, et j'avais besoin d'un DataTable dans mon code-behind, c'est exactement comme ça que je l'ai fait. –

+0

@Bon Sommardahl: merci! qu'est-ce que vous utilisez maintenant? – abatishchev

+0

Eh bien, afin d'avoir plus de contrôle et de tester correctement, je lie mes contrôles serveur à un ensemble de données de code-behind. Je posterai une réponse avec un exemple. –

Répondre

1

Je préfère lier mes contrôles serveur dans mon code-behind. Je peux déboguer et tester cela mieux. Je n'ai pas besoin de faire d'autres choses folles pour accéder à mes données liées à partir de code-behind ... c'est déjà là. Voici un exemple.

Assumer le proc stocké suivant dans SQL:

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

je peux correspondre à celui stocké proc à une méthode dans ma classe d'entité ou d'une page code-behind, comme ceci:

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; 
    } 

Ensuite, Je peux simplement lier mes données à mon contrôle serveur à la page_load comme ceci:

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

Si vous essayez ceci, assurez-vous de rem transférez le paramètre DataSourceId de GridView dans votre balisage. DataSource et DataSourceId ne jouent pas bien ensemble.

Remarque: Il existe en réalité un million de meilleures façons de le faire. Le but de ce post était d'illustrer une alternative facile à l'utilisation de SqlDataSource dans votre mark-up.

Une façon de prendre ce une futher étape consiste à attribuer l'ensemble de données résultant à une variable réutilisable comme une propriété de page:

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(); 
     } 
    } 
} 

Avec cette mise à niveau simple, vous avez la possibilité d'utiliser et réémergentes utilisez le DataSet sur toute la page sans avoir à re-interroger la base de données.

+0

@Bon Sommardahl: Merci beaucoup! Très intéressant. Et frais. Et la prochaine étape pourriez-vous recommander? Je veux dire votre phrase "Il y a en réalité un million de meilleures façons de faire cela". – abatishchev

+0

Je me sens comme la prochaine étape serait de devenir plus orienté objet dans votre pensée. Dans ma propre progression, je suis passé de travailler avec des ensembles de données à travailler avec des listes génériques et des objets. Ainsi, au lieu d'un ensemble de lignes de clients, j'ai une liste fortement typée d'objets clients. –

+0

Une façon de se déplacer dans cette direction est d'essayer les classes Linq to SQL (google cela). Une fois que vous avez maîtrisé cela, vous pouvez passer à Entity Framework (ou tout ce qui est "dans le style" à la fois). Quelqu'un pourrait avoir de meilleures suggestions. –