Devexpress pivot grid bind to vanilla SQL statement - asp.net-mvc-4

I have a test DX pivot grid that I'm attempting to attach a simple SQL statement against (fairly trite example I know, but I'm just "proof of concept"ing here)
#Html.DevExpress().PivotGrid(settings =>
{
settings.Name = "pivotGrid";
settings.CallbackRouteValues = new { Controller = "Home", Action = "PivotGridPartial" };
settings.OptionsView.ShowHorizontalScrollBar = true;
settings.Height = new Unit(887, UnitType.Pixel);
settings.Width = new Unit(100, UnitType.Percentage);
settings.OptionsCustomization.CustomizationFormStyle = CustomizationFormStyle.Excel2007;
var dataTable = new DataTable();
using (var con = new SqlConnection(#"Data Source=.\WHATEVER;Initial Catalog=WhatEver;integrated security=true;"))
{
con.Open();
var adapter = new SqlDataAdapter("select * from dbo.WhatEver", con);
adapter.Fill(dataTable);
}
settings.PreRender = (sender, e) =>
{
var pivot = ((MVCxPivotGrid)sender);
pivot.DataSource = dataTable;
pivot.RetrieveFields(PivotArea.FilterArea, false);
pivot.BeginUpdate();
pivot.Fields["Client"].Area = PivotArea.RowArea;
pivot.Fields["Client"].Visible = true;
pivot.Fields["Brand"].Area = PivotArea.RowArea;
pivot.Fields["Brand"].Visible = true;
pivot.Fields["Volume"].Area = PivotArea.DataArea;
pivot.Fields["Volume"].Visible = true;
pivot.EndUpdate();
};
}).GetHtml()
This works perfectly when it loads, but then if I try to expand one of the dimensions or change to another page the grid gets blanked out, i.e. like it has no data assigned against it.
Would anyone have an idea as to why? I can't find anything relating to pivot grids and DX that doesn't assume using an OLAP cube and the examples I have found (all around Access) seem to be doing what I'm attempting but obviously I'm missing something!
Thanks in advance!

It's because I'm an idiot and had the datasoruce assignment in the prerender section

Related

Passing DropDownList value into SQL command in ASP.net

I have a DropDownList which gets it values from SQL table
I want to get the Average of the selected item (course in this case) from the dropDownList and to show it in a label :
This section works -
SqlConnection sqlConnection1;
sqlConnection1 = new SqlConnection(#"Data Source=HA\SQLEXPRESS; Initial Catalog=Grades1; Integrated Security=True");
SqlCommand Command = null;
Command = new SqlCommand("SELECT Course FROM GradesTable1", sqlConnection1);
Command.Connection.Open();
SqlDataAdapter dataAdapter = new SqlDataAdapter(Command);
DataTable dataTble1 = new DataTable();
dataAdapter.Fill(dataTble1);
if (dataTble1.Rows.Count > 0)
{
foreach (DataRow row in dataTble1.Rows)
{
ListItem course1 = new ListItem(row["Course"].ToString());
if (!DropDownList1.Items.Contains(course1))
{
DropDownList1.Items.Add(course1); // showing the 2 courses
}
}
}
Command.Connection.Close();
}
}
Here is the problem - (I get nothing, no data )
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
SqlConnection sqlConnection1;
sqlConnection1 = new SqlConnection(#"Data Source=HA\SQLEXPRESS; Initial Catalog=Grades1; Integrated Security=True");
SqlCommand Command = null;
Command = new SqlCommand($"SELECT AVG(Grade) FROM GradesTable1 WHERE Course = #course", sqlConnection1);
Command.Parameters.AddWithValue("#course", DropDownList1.SelectedItem);
Command.Connection.Open();
SqlDataReader sqlDataReader1 = Command.ExecuteReader();
if (sqlDataReader1.Read())
{
LabelAverage.Text = sqlDataReader1[0].ToString();
}
else
{
LabelAverage.Text = "No Data"; // doesn't get into here anyhow
}
}
EDIT
I tried several variations as $"SELECT AVG(Grade) AS "ClassAVG" FROM GradesTable1 WHERE Course = #course" and Command.Parameters.AddWithValue("#course", DropDownList1.SelectedItem.Text), or DropDownList1.SelectedValue
I believe the problem is with the DropDownlist values which being received from the SQL and are not hard coded.
Is there a correct way to this? is it possible without knowing what are the "Courses" in advanced?
Thanks for the answers, feel free to give your opinion.
I found out what was missing in the DropDownList in aspx page (not the aspx.cs page) -the AutoPostBack="true"
Adding that to DropDownList solved the problem.
// query = Sql query
query.Select(s => new MusteriNoktaComboItemDTO
{
Label = s.Adi,
Value = s.ID.ToString()
}).ToList();

c# Copy SQL table data to another DB with Where clause filter using Data Factory

I am in a process to copy data from one SQL database (Source) and move to another SQL Database (destination) through data factory using c# code.
I am able to copy all the data from a source table to destination table, but i want to move filtered data only, like SELECT * FROM Source.tbl WHERE Category = 5. There would be around 10-15 table that i would move data. Can you provide me sample code which may help me?
My code for moving single table all data..
// Authenticate and create a data factory management client
var context = new AuthenticationContext("https://login.windows.net/" + tenantID);
ClientCredential cc = new ClientCredential(AppID, AuthKey);
AuthenticationResult result = context.AcquireTokenAsync("https://management.azure.com/", cc).Result;
ServiceClientCredentials cred = new TokenCredentials(result.AccessToken);
var client = new DataFactoryManagementClient(cred) { SubscriptionId = SubscriptionID };
// Create data factory
Factory dataFactory = new Factory { Location = Region, Identity = new FactoryIdentity() };
// This line throws error, we cannot proceed further. unless we get access of creating DF or update or access.
client.Factories.CreateOrUpdate(ResourceGroup, DataFactoryName, dataFactory);
var DF = client.Factories.Get(ResourceGroup, DataFactoryName);
while (DF.ProvisioningState == "PendingCreation")
{
System.Threading.Thread.Sleep(1000);
}
LinkedServiceResource storageLinkedService = new LinkedServiceResource(
new AzureSqlDatabaseLinkedService
{
ConnectionString = new SecureString(SourceSQLConnString)
}
);
client.LinkedServices.CreateOrUpdate(ResourceGroup, DataFactoryName, SourceSQLLinkedServiceName, storageLinkedService);
LinkedServiceResource sqlDbLinkedService = new LinkedServiceResource(
new AzureSqlDatabaseLinkedService
{
ConnectionString = new SecureString(DestSQLConnString)
}
);
client.LinkedServices.CreateOrUpdate(ResourceGroup, DataFactoryName, DestSQLLinkedServiceName, sqlDbLinkedService);
DatasetResource SourceSQLDataSet = new DatasetResource(
new AzureSqlTableDataset
{
LinkedServiceName = new LinkedServiceReference
{
ReferenceName = SourceSQLLinkedServiceName
},
TableName = Table,
}
);
client.Datasets.CreateOrUpdate(ResourceGroup, DataFactoryName, SourceSQLDataSetName, SourceSQLDataSet);
// Create a Azure SQL Database dataset
DatasetResource DestSQLDataSet = new DatasetResource(
new AzureSqlTableDataset
{
LinkedServiceName = new LinkedServiceReference
{
ReferenceName = DestSQLLinkedServiceName
},
TableName = Table
}
);
client.Datasets.CreateOrUpdate(ResourceGroup, DataFactoryName, DestSQLDataSetName, DestSQLDataSet);
PipelineResource pipeline = new PipelineResource
{
Activities = new List<Activity>
{
new CopyActivity
{
Name = "CopyFromSQLToSQL",
Inputs = new List<DatasetReference>
{
new DatasetReference()
{
ReferenceName = SourceSQLDataSetName
}
},
Outputs = new List<DatasetReference>
{
new DatasetReference
{
ReferenceName = DestSQLDataSetName
}
},
Source = new SqlSource(),
Sink = new SqlSink { }
}
}
};
client.Pipelines.CreateOrUpdate(ResourceGroup, DataFactoryName, PipelineName, pipeline);
// Create a pipeline run
CreateRunResponse runResponse = client.Pipelines.CreateRunWithHttpMessagesAsync(ResourceGroup, DataFactoryName, PipelineName).Result.Body;
// Monitor the pipeline run
PipelineRun pipelineRun;
while (true)
{
pipelineRun = client.PipelineRuns.Get(ResourceGroup, DataFactoryName, runResponse.RunId);
if (pipelineRun.Status == "InProgress")
System.Threading.Thread.Sleep(15000);
else
break;
}
You could put your query into the SqlReaderQuery property of your sql Source.
I talked to the Data Factory support, they said we have not implemented yet,
Create Data Factory,
Create linked services
In loop create datasets and Create copy activity

Manually Sorting Data in Gridview in asp.Net Webforms

I am having some difficult manually sorting data on a gridview. I used a dataset and when set the AllowSort to true and also wrote the code to handle the sort based on the guide given on https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.sorting.aspx . However, when I run my code, the data displays but when I click the header of each column, nothing happens.
here is my code
protected void Page_Load(object sender, EventArgs e)
{
string connstring = ConfigurationManager.ConnectionStrings["Conn"].ConnectionString;
SqlConnection conn = new SqlConnection(connstring);
conn.Open();
SqlCommand comm = conn.CreateCommand();
comm.CommandText = "SELECT Count(Student.StudentID) AS StdCount, Schools.Name, Schools.StartDate, School.SchoolFees FROM Schools INNER JOIN Students ON Schools.SchoolID = Student.SchoolID WHERE School.Active = 1 GROUP BY Schools.Name, Schools.StartDate, Schools.SchoolFess ORDER BY Schools.Name ASC";
SqlDataAdapter da = new SqlDataAdapter(comm);
DataSet ds = new DataSet();
da.Fill(ds);
if (ds.Tables.Count > 0)
{
DataTable dt = ds.Tables[0];
ViewState["datable"] = dt;
}
GridView1.DataSource = ds;
GridView1.DataBind();
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
//Retrieve the table from the session object.
DataTable dt = (DataTable)ViewState["datable"];
if (dt != null)
{
//Sort the data.
dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
GridView1.DataSource = ViewState["datable"];
GridView1.DataBind();
}
}
private string GetSortDirection(string column)
{
// By default, set the sort direction to ascending.
string sortDirection = "ASC";
// Retrieve the last column that was sorted.
string sortExpression = ViewState["SortExpression"] as string;
if (sortExpression != null)
{
// Check if the same column is being sorted.
// Otherwise, the default value can be returned.
if (sortExpression == column)
{
string lastDirection = ViewState["SortDirection"] as string;
if ((lastDirection != null) && (lastDirection == "ASC"))
{
sortDirection = "DESC";
}
}
}
// Save new values in ViewState.
ViewState["SortDirection"] = sortDirection;
ViewState["SortExpression"] = column;
return sortDirection;
}
Any help will be appreciated. Thanks
You need to bind the DefaultView of the DataTable, which is this orderly, not ViewState variable.
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
//Retrieve the table from the session object.
DataTable dt = (DataTable)ViewState["datable"];
if (dt != null)
{
//Sort the data.
dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
GridView1.DataSource = dt.DefaultView;
GridView1.DataBind();
}
}
This looks to be a Page LifeCycle issue.
Every time you post back the entire Page LifeCycle runs
In your case you are retrieving and overwriting ViewState["datable"] on every postback, assuming of course that if (ds.Tables.Count > 0) evaluates to true.
And then you do this in Page Load:
GridView1.DataSource = ds;
but in your sorting routine you access:
DataTable dt = (DataTable)ViewState["datable"];
...
GridView1.DataSource = ViewState["datable"];
You just replaced GridView.DataSource, which initially was a DataSet, with a DataTable
Wrap your initial data Retrieval in PageLoad like this
if( !Page.IsPostback )
{
// This retrieves Data once, and you persist it
// in the ViewState no need to Keep retrieving it
// unless the data has changed
}
// Rebind outside the if
GridView1.DataSource = (DataTable) ViewState["datable"];
GridView1.DataBind();
Addendum
Per Andrei he is correct. ViewState is a hidden field on your rendered ASPX. View the page source in your browser and search for
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="" />
It's Ok to use as a learning aid as long as the dataset is small and doesn't contain any confidential information.
But as it's transmitted to and from your page on every postback you incur a lot of overhead. Imagine if your DataSet contained several thousand rows.
Session State is a better option, but the Application Cache is better still. Server Data Controls like SqlDataSource make use of this cache and so can you. Access it just like ViewState:
ViewState["datable"] = dt;
Cache["datable"] = dt;
But don't go crazy with it. ViewState, SessionState, Cookies, LocalStorage, etc all have their place, learn them.

Monitor multiple tables related or non-related with sqldependency and signalr

I am trying to monitor multiple tables using signalR. These tables are related, but I need all columns from all tables for display purposes. I have seen SQldependcy on one table. How to implement it for multiple tables? Is this the right way to implement sqldependecy and signalr for multiple tables? In the database there are different tables with each having the ForiegnKey master--->submaster--->detail. Please suggest!
var masterpc = new List<master_Table>();
var submaster = new List<submaster_Table>();
var detail = new List<detail_Table>();
using (SqlConnection connection = new SqlConnection(regularConnectionString))
{
using (SqlCommand command = new SqlCommand(commandText, connection))
{
connection.Open();
//var dependency = new SqlDependency(command);
//dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
// NOTE: You have to execute the command, or the notification will never fire.
var reader = command.ExecuteReader();
while (reader.Read())
{
masterpc.Add(item: new master_Table
{
MasterKeyId = (int)reader["MasterKeyId"],
Master_Name = (string)reader["Master_Name"],
Master_IP = reader["Master_IP"] != DBNull.Value ? (string)reader["Master_IP"] : "",
Master_Valid = (bool)reader["Master_Valid"],
});
count++;
}
masterViewModel.masterpc_info = masterpc;
}
}
count = 0;
using (SqlConnection connection = new SqlConnection(regularConnectionString))
{
commandText = "select * from submaster where master_Valid=1 and masterKeyId in(select masterKeyId from masterpc_table where id=24) ";
using (SqlCommand command = new SqlCommand(commandText, connection))
{
connection.Open();
//var dependency = new SqlDependency(command);
//dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
// NOTE: You have to execute the command, or the notification will never fire.
var reader = command.ExecuteReader();
while (reader.Read())
{
submaster.Add(item: new submaster_table
{
SubmasterKeyId = (int)reader["SubmasterKeyId"],
submaster_Type = (string)reader["submaster_Type"],
submaster_SN = reader["submaster_SN"] != DBNull.Value ? (string)reader["submaster_SN"] : "",
masterPCKeyId = (int)reader["masterPCKeyId"],
});
count++;
}
masterconfigViewModel.submasterinfo = submaster;
}
}
using (SqlConnection connection = new SqlConnection(regularConnectionString))
{
commandText = "select * from detail where submasterKeyId in(select submasterkeyid from masterpc_table where id=24) ";
using (SqlCommand command = new SqlCommand(commandText, connection))
{
connection.Open();
var dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
// NOTE: You have to execute the command, or the notification will never fire.
var reader = command.ExecuteReader();
while (reader.Read())
{
detail.Add(item: new detail_table
{
detailkeyid = (int)reader["detailkeyid"],
detail_Type = (string)reader["detail_Type"],
detail_status = reader["detail_status"] != DBNull.Value ? (string)reader["detail_status"] : "",
submasterkeyid = (int)reader["submasterkeyid"],
});
count++;
}
masterconfigViewModel.detailinfo = detail;
}
}
This might be little late to answer, but you might think the following option suitable for you.
Project known as SqlDependencyEx
https://github.com/dyatchenko/ServiceBrokerListener
How to use for multiple tables
All you need to do is to create multiple listeners with different
identities as shown below:
var listener1 = new SqlDependencyEx(connectionString, "YourDatabase", "YourTable1", identity: 1);
var listener2 = new SqlDependencyEx(connectionString, "YourDatabase", "YourTable2", identity: 2);

SQL (lite) replace string value in all columns with formatting

I'm trying to update a SQLite database with a column "URL" with a specific value. The old url format is "http://www.blz.nl/voster/boek/9789056628512" and the new one is "http://www.blz.nl/voster/boekwinkel/zoeken/?q=9780789327505&oa=true&searchin=taal&taal=dut".
What I am trying to do is replace the url to the new format but keep the value of the 'Q' param from the old url. What is the fastest / best way to achieve this for all columns? I have no idea how to approach this using an SQL query.
You want the SQL?
Basically, you read in the table, search for your keyword, replace it, and write that data back to the database.
Assuming your database name is "mydatabase.db", your code would look something like this (untested):
using Devart.Data.SQLite;
public void Convert()
{
using (var conn = new SQLiteConnection("DataSource=mydatabase.db"))
{
var boek = "//boek//";
var boekwinkel = "//boekwinkel//";
var boek_len = boek.Length;
var table = new DataTable();
var sqlCmd = "SELECT * FROM TableName1;";
conn.Open();
// Read the data into the DataTable:
using (var cmd = new SQLiteCommand(sqlCmd, conn))
{
// The DataTable is ReadOnly!
table.Load(cmd.ExecuteReader());
}
// Use a new SQLiteCommand to write the data.
using (var cmd = new SQLiteCommand("UPDATE TableName1 SET URL=#NEW_URL WHERE URL=#URL;", conn))
{
cmd.Parameters.Add("#URL", SQLiteType.Text, 20);
cmd.Parameters.Add("#NEW_URL", SQLiteType.Text, 20);
foreach (DataRow row in table.Rows)
{
var url = String.Format("{0}", row["URL"]).Trim();
cmd.Parameters["#URL"].SQLiteValue = row["URL"];
if (!String.IsNullOrEmpty(url))
{
var index = url.IndexOf(boek);
if (-1 < index)
{
var first = url.Substring(0, index);
var middle = boekwinkel;
var last = url.Substring(index + boek_len);
var new_url = String.Format("{0}{1}{2}&oa=true&searchin=taal&taal=dut", first, middle, last);
// Place a break point after String.Format.
// Make sure the information being written is correct.
cmd.Parameters["#NEW_URL"].SQLiteValue = new_url;
cmd.ExecuteNonQuery();
}
}
}
}
conn.Close();
}
}