Appending LINQ to exist datasource/gridview in C# - c#

I have the following in my .aspx page:
<asp:GridView ID="Table1" runat="server" AutoGenerateColumns="False" BorderColor="Black" OnRowCreated="Table1_RowCreated" OnRowDataBound="Table1_RowDataBound" CellPadding="3" CellSpacing="0" DataSourceID="Table1DataSrc" DataKeyNames="Field1">
<Columns>
<asp:BoundField DataField="Field1" HeaderText="Field1" SortExpression="Field1">
<ItemStyle HorizontalAlign="Left" Font-Size="8" Wrap="false" />
<HeaderStyle CssClass="header" Font-Size="8" />
</asp:BoundField>
</Columns>
</asp:GridView>
Where the gridview has a DataSource that loads a few fields. In my C# code behind, I have the following function which runs a LINQ query to process a stored procedure (on a different server than my other datasource)
private void RenderTables()
{
SqlDataAdapter adapter = new SqlDataAdapter();
DataTable dt = new DataTable();
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand("sp_special", conn);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#AmIY", "Y");
adapter.SelectCommand = cmd;
adapter.Fill(dt);
adapter.Dispose();
conn.Close();
}
var enumvar = dt.AsEnumerable();
var query = from x in enumvar
orderby x.Field<string>(3)
select new
{
Field3 = x.Field<string>(3),
Field4 = x.Field<int>(4),
};
//I do some data manipulation using LINQ, but omitted here
//do something with query.....
}
How would I add new columns Field3 and Field4 to my Gridview and bind these new records? I do not want to store anything in temp tables on either servers

it will work like this...
<asp:BoundField DataField="Field3" HeaderText="Field3" SortExpression="Field3">
<asp:BoundField DataField="Field4" HeaderText="Field4" SortExpression="Field4">

Related

Populate ASP DataGrid With Fields With Spaces

I have a SQL Server table that has fields with spaces in it. I am attempting to populate an asp datagrid with this information, but on the Bind() event I keep getting an error of
Additional information: A field or property with the name '[Field With Space]' was not found on the selected data source.
I know the field is properly named as if I run it in SSMS it executes properly. Below is my HTML and my C# - what is set-up incorrectly?
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["LSTMain"].ConnectionString))
{
cn.Open();
SqlCommand cmd = new SqlCommand("SELECT [Field With Space] FROM [Inventory Log] order by ID ASC", cn);
SqlDataReader dr = cmd.ExecuteReader();
GridView1.DataSource = dr;
GridView1.DataBind();
cn.Close();
}
<div id="dgv">
<asp:GridView ID="GridView1" runat="server" CssClass="Grid" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="[Field With Space]" HeaderText="SQL Field With Spaces" />
</Columns>
</asp:GridView>
you can use the datareader dr.GetString(0)

Better solution to SqlDataSource?

I need to display some data from a view in a SQL Server database on several pages of my website. I've done it by using SqlDataSource within my web.config and then used a GridView control within my .aspx page to display the data.
Now, this works but I read in some forum that it is bad practice to do use SqlDataSource? I will probably need to have the ability for the admin/user to filter the data in the future, so I'm not sure how this would work with my current implementation.
My code so far looks like this :
In the web.config file:
<connectionStrings>
<add name="Test1.ConnectionString"
connectionString="Data Source=...."
providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
And something like this in my aspx
<body id="wrap" >
<form runat="server">
<asp:GridView ID="GridView1" runat="server" AllowSorting="True" AutoGenerateColumns="False"
BackColor="White" BorderColor="#CCCCCC"
BorderStyle="None" BorderWidth="1px" CellPadding="3"
DataSourceID="SqlDataSource1" Height="500px" Width="408px">
<Columns>
<asp:BoundField DataField="Title" HeaderText="Title" ReadOnly="True" SortExpression="Title">
<ItemStyle Width="400px" HorizontalAlign="Center" Height="100px" BorderColor="#CCCCCC" BorderStyle="Solid" BorderWidth="1px" />
</asp:BoundField>
<asp:BoundField DataField="Result" HeaderText="Result" ReadOnly="True" SortExpression="Result" >
<ItemStyle HorizontalAlign="Center" Height="100px" BorderColor="#CCCCCC" BorderStyle="Solid" BorderWidth="1px" />
</asp:BoundField>
</Columns>
<FooterStyle BackColor="White" ForeColor="#002756" />
<HeaderStyle BackColor="#003466" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="White" ForeColor="#002756" HorizontalAlign="Left" />
<RowStyle ForeColor="#002756" />
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings: Test1.ConnectionString %>"
SelectCommand="SELECT * FROM [Test1.ConnectionString]">
</asp:SqlDataSource>
</form>
</body>
So my question is is there a better way to implement this, keeping in mind that I will probably need a function for the user/admin to filter the data by certain criteria?
It's not necessarily bad practice to use SqlDataSource... but it does tend to mingle your data access code with your presentation code. Additionally, you can often do better with an ObjectDataSource that wraps your view. There's a little more code involved (you'll have to create a new class somewhere to select from your view), but you end up with methods that can be easily updated or replaced in the future to handle whatever changes you may need.
As mentioned in my comment I would recommend you use the code behind to achieve this as it's much easier to make changes if required in the future. I'm assuming you've got a table in your database named Test1. We'll first create a class to represent this in C# and add a few properties which we'll use later on.
public class Test
{
public string Title { get; set; }
public int Result { get; set; }
}
Now let's create a method which returns a collection of values from your database.
public List<Test> GetData()
{
List<Test> myList = new List<Test>();
string sqlQuery = "Select Title, Result From Test";
string connectionString = ConfigurationManager.ConnectionStrings["Test1.ConnectionString"].ConnectionString; //Read connection string from config file
using (var con = new SqlConnection(connectionString))
{
using (var cmd = new SqlCommand(sqlQuery, con))
{
//Add param here if required.
con.Open(); //Open connection
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
Test t = new Test();
t.Title = reader["Title"].ToString();
t.Result = Convert.ToInt32(reader["Result"]);
myList.Add(t);
}
}
}
}
return myList;
}
Finally, you want to set the datasource for the GridView. I'm going to assume you have a page called MyGridPage.aspx open up the MyGridPage.asps.cs and in your Page_Load event you can set the DataSource for your grid as:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Test t = new Test();
GridView1.DataSource = t.GetData();
GridView1.DataBind();
}
}
If you wanted to filter your Sql query by for example username you'll change it as:
string sqlQuery = "Select Title, Result From Test Where username = #username";
Then you can pass in the #username parameter as:
cmd.Parameters.Add("#username", SqlDbType.NVarChar).Value = myUsername;
myUsername can be of someone who's logged into your app. You will pass the parameter(s) before you open the connection. Passing parameters will also prevent sql injection which I suggest you read up on in case you're not aware.
Note: it is recomenned to make use of using block to ensure the connection object is closed and disposed correctly.
You can programmatically set the data source of the grid view.
protected void Page_Load(object sender, EventArts e)
{
using(SqlConnection conn = new SqlConnection(connectionString))
{
string query = "SELECT * FROM Test"; //your SQL query goes here
SqlCommand cmd = new SqlCommand(query, conn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable table = new DataTable();
da.Fill(table);
GridView1.DataSource = table;
GridView1.DataBind();
cmd.Dispose();
da.Dispose();
}
}

Select statement not working properly in SqlCommand

I'm using the below code to create an sql data grid on a web page in an ASP.Net web application.
private void BindGrid()
{
string strConnString = "server= N-1077; Trusted_Connection=yes; database=Slaughter; connection timeout=30";
using (SqlConnection con = new SqlConnection(strConnString))
{
using (SqlCommand cmd = new SqlCommand("SELECT WeekEndingDate = CONVERT(date, Week_Ending_Date, 103), Week_Number, North_Island, South_Island FROM Slaughter ORDER BY WeekEndingDate DESC"))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (DataTable dt = new DataTable())
{
sda.Fill(dt);
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
}
}
}
I'm not sure why but when I call the select statement - "SELECT WeekEndingDate = CONVERT(date, Week_Ending_Date, 103), Week_Number, North_Island, South_Island FROM Slaughter ORDER BY WeekEndingDate DESC" - the WeekEndingDate still shows up on the web page with the datetime.
If I run the same command in Sql Server it does it correctly.
So what am I doing wrong here? Here is the html side of things just in case that is the problem.
<div style="width: 1250px; height: 300px; overflow: auto">
<asp:GridView ID="GridView1" HeaderStyle-BackColor="#6699ff" HeaderStyle-ForeColor="Black" RowStyle-BackColor="#ccffff" AlternatingRowStyle-BackColor="White"
AlternatingRowStyle-ForeColor="#000" runat="server" AutoGenerateColumns ="false" AllowPaging="false" OnPageIndexChanging="OnPageIndexChanging" AllowSorting="True">
<Columns>
<asp:BoundField DataField ="WeekEndingDate" HeaderText="Week Ending Date" ItemStyle-Width="150px" />
<asp:BoundField DataField ="Week_Number" HeaderText="Week Number" ItemStyle-Width="150px" />
<asp:BoundField DataField ="North_Island" HeaderText="North Island" ItemStyle-Width="150px" />
<asp:BoundField DataField ="South_Island" HeaderText="South Island" ItemStyle-Width="150px" />
</Columns>
</asp:GridView>
</div>
This will format date:
<asp:BoundField DataField ="WeekEndingDate" HeaderText="Week Ending Date" ItemStyle-Width="150px" dataformatstring="{0:MM-dd-yyyy}"/>
CONVERT(date, Week_Ending_Date, 103) converts the value of Week_Ending_Date to a date datatype in the returned dataset. .NET receives that as a DateTime and the default string format of a DateTime includes the time value. That's why your web page has the time displayed. If you do not want the time displayed, convert the value to a string either in your SQL: CONVERT(nvarchar(10), Week_Ending_Date, 103) or in your ASP tag: dateformatstring="{0:d}" or dateformatstring="{0:dd-MM-yyyy}" if your current culture settings don't give you the format you want with the first one.

In c#, my datagrid is not showing the rows

I have a datagrid which I fill with a data set, several are done this way and they work, just one does not, why?
Code
<asp:DataGrid ID="dgServer" runat="server"
AutoGenerateColumns="False" AllowSorting="True"
ondeletecommand="dataGrid1_DeleteCommand"
oneditcommand="dataGrid1_EditCommand"
OnSortCommand="dataGrid1_SortCommand">
<AlternatingItemStyle BackColor="#C1D0EC" />
<Columns>
<asp:EditCommandColumn CancelText="Cancel" EditText="Editar"
UpdateText="Update">
<HeaderStyle Wrap="False" />
<ItemStyle Wrap="False" />
</asp:EditCommandColumn>
<asp:ButtonColumn CommandName="Delete" Text="Borrar"></asp:ButtonColumn>
<asp:BoundColumn DataField="Id" HeaderText="Id" SortExpression="Id"
Visible="False"></asp:BoundColumn>
<asp:BoundColumn DataField="Server" HeaderText="Servidor"
SortExpression="Server" >
</asp:BoundColumn>
<asp:BoundColumn DataField="Port" HeaderText="Puerto" SortExpression="Port"
></asp:BoundColumn >
<asp:BoundColumn DataField="User" HeaderText="Usuario" SortExpression="User"
></asp:BoundColumn >
<asp:BoundColumn DataField="Password" HeaderText="Password" SortExpression="Password"
></asp:BoundColumn >
<asp:BoundColumn DataField="PassAuten" HeaderText="PassAut" SortExpression="PassAut">
</asp:BoundColumn>
</Columns>
<EditItemStyle BackColor="#CCCCCC" />
<HeaderStyle BackColor="#0B63A2" ForeColor="White" />
</asp:DataGrid>
How is done in every other and it works:
public void LlenarDataGridServer()
{
//read = Con.executar_re("Select * from SMTP");
//dataGrid1.DataSource = read.Tables[0];
//dataGrid1.DataBind();
DataSet verServer = Con.executar_re("select * from dbo.smtp");
dgServer.DataSource = verServer.Tables[0];
dgServer.DataBind();
}
So whats up, this is killing me. Thanks.
Edit: Yes the table is set up, I can access the data from sql server and is 1 row which I plan to update.
2 Edit: The same lines are filling other DG like
public void LlenarDatagridConsecutivos()
{
read = Con.executar_re("select * from TypeCConsecutiveDocument");
dgConsecutivos.DataSource = read.Tables[0];
dgConsecutivos.DataBind();
}
And the Con.etc:
public DataSet executar_re(string comando)
{
try
{
connnection01.Open();
SqlCommand command01 = new SqlCommand();
command01.CommandText = comando;
command01.Connection = connnection01;
SqlDataReader re01 = command01.ExecuteReader(CommandBehavior.CloseConnection);
DataSet ds = Convert(re01);
re01.Close();
connnection01.Close();
return ds;
}
catch (SqlException sqle)
{
System.Diagnostics.Debug.WriteLine(sqle.ToString());
DataSet ds = new DataSet();
return ds;
}
I don't know what is going on in that Convert method, but, see this link about how to use a SqlDataReader: http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.aspx
Should be something like this:
List<IDataRecord> records = new List<IDataRecord>();
while(re01.Read())
{
//add record to list
records.Add((IDataRecord)re01);
}
//records now has your list of data.
re01.close();
I got it, it was something really strange:
I change the table name from smtp to mailServer
I put the column name's in [name]
I got rid of the DG and put it in a label which changes
I think is more likely to be 1, 2.
Something funny is going on with some name :o
Edited: to look better

Binding GridView to SqlDataSource programmatically

I'm trying to replicate the binding in my markup with something programmatic.
It seems I am forced to use a dataset to bind to rather than a SqlDataSource as shown in my markup.
Furthermore, when using a dataset, I suddenly lose paging, sorting, etc., and get errors that I need to handle them manually.
They were handled automatically before??
So here is my markup:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="True"
CellPadding="4" DataSourceID="SqlDataSource1" ForeColor="#333333"
GridLines="None" AllowPaging="True" AllowSorting="True" Width="520px">
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
<Columns>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand="CustOrdersOrders" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter Direction="ReturnValue" Name="RETURN_VALUE" Type="Int32" />
<asp:ControlParameter ControlID="txtCustId" DefaultValue="AROUT"
Name="CustomerID" PropertyName="Text" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
I replaced it with something like this:
SqlDataAdapter adapter = new SqlDataAdapter();
conn.Open();
using (SqlConnection conn = new SqlConnection(connStr))
{
SqlDataAdapter adapter = new SqlDataAdapter();
conn.Open();
using (SqlCommand cmd = new SqlCommand("CustOrdersOrders", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("CustomerID", "AROUT");
cmd.ExecuteScalar();
adapter.SelectCommand = cmd;
}
GridView1.DataSource = adapter;
GridView1.DataBind();
}
This ofcourse raises an error that that the data source is not of the correct type, yet this is exactly what the markup does.
The only thing I can think of is that is uses DataSource instead of DataSourceID.
So how do I replicate this markup and get all the sorting and paging automatically?
If I have to use a dataset, why does the markup not require one?
But, even with the dataset, it doesn't seem to handle the paging and sorting automatically like I said.
Thanks!
Levi
You can not set the DataAdapter as the DataSource property value.SqlDataAdapter provides the communication between the Dataset and the SQL database. You must be using the data adapter to fill a DataTable /DataSet and use that as the DataSource.
Your code had some other problems
1) You are trying to open a connection before declaring it.
2) Sql Data adapter object is created twice with same name.
The below code will work
using (SqlConnection conn = new SqlConnection(connStr))
{
SqlDataAdapter adapter = new SqlDataAdapter();
conn.Open();
DataTable dt = new DataTable();
using (SqlCommand cmd = new SqlCommand("CustOrdersOrders", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("CustomerID", "AROUT");
adapter.SelectCommand = cmd;
adapter.Fill(dt);
}
GridView1.DataSource = dt;
GridView1.DataBind();
}
http://www.dotnetperls.com/sqldataadapter
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldataadapter.aspx

Categories

Resources