Trying to remove duplicate treenodes when adding data from sql server.
Data is added to tree ok but I can't seem to work out how to remove duplicates of the parent nodes.
public partial class SYS_Main : System.Web.UI.Page
{
public TreeNode testerr = new TreeNode();
private List<string> _isdupe = new List<string>();
private List<string> _dupe = new List<string>();
protected void Page_Load(object sender, EventArgs e)
{
PopulateRootLevel();
TV_Test.CollapseAll();
}
private void PopulateRootLevel()
{
const string connectionString = ("user=;" +
"password=;server =UsersSQL;" +
"Trusted_Connection=yes;" +
"database=System Details; " +
"connection timeout=30");
// connects to sql DB
// sql connection
SqlConnection objConn = new SqlConnection(connectionString);
// sql queries to server
SqlCommand objCommand = new SqlCommand("SELECT Contract, [Server Name],[IP Address] FROM tblServers where Contract !='' AND [SERVER NAME] !='';", objConn);
SqlCommand testquery = new SqlCommand("select s.contract ,COUNT(*)from [System Details].dbo.tblServers s where contract !='' group by Contract having count (*)>1 ;", objConn);
// data adapater holds values of sql queries
SqlDataAdapter da = new SqlDataAdapter(objCommand);
// datatable to hold query data into nodes
DataTable dt = new DataTable();
// data table populated
da.Fill(dt);
//Calls popnodes method and includes dt + nodes for
PopulateNodes2(dt,TV_Test.Nodes);
}
//pop nodes method
private void PopulateNodes2(DataTable dt, TreeNodeCollection nodes)
{
foreach (DataRow dr in dt.Rows)
{
TV_Test.Nodes.Clear();
TreeNode IP = new TreeNode();
IP.Text = dr["IP Address"].ToString();
// new instance of a treenode
testerr = new TreeNode();
testerr.Text = dr["Server Name"].ToString();
testerr.ChildNodes.Add(IP);
TreeNode parent = new TreeNode("Text1");
parent.Text = "keyText1";
parent.Text = (dr["Contract"]).ToString();
_isdupe.Add(parent.Text);
parent.ChildNodes.Add(testerr);
nodes.Add(parent);
string trued;
trued = _isdupe.Distinct().ToString();
if (trued.Equals(parent.Text))
{
TV_Test.Nodes.Remove(parent);
}
else
{
}
}
}
}
}
I think your algorithm is wrong, if you order your query you'll be able to fill the treeview with no duplicate directly.
Related
I had a problem generating a word template because I wanted it to be selected dynamically with ddlTemplate when selected to write in it with the merge field in the word template.
this is my code:
public partial class unTemplate : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)// call the method for ONLY first time for visitor
{
{
populateDdlInstitution();
}
}
}
protected void populateDdlInstitution()
{
CRUD myCrud = new CRUD();
string mySql = #"select institutionid, institution from institution";
SqlDataReader dr = myCrud.getDrPassSql(mySql);
ddlInstitution.DataTextField = "institution";
ddlInstitution.DataValueField = "institutionid";
ddlInstitution.DataSource = dr;
ddlInstitution.DataBind();
}
protected void ddlInstitution_SelectedIndexChanged(object sender, EventArgs e)
{
// call a method to populate the template ddl
populateDdlTemplate();
}
protected void populateDdlTemplate()
{
CRUD myCrud = new CRUD();
string mySql = #"select internDocId, DocName
from internDoc
where institutionId = #institutionId";
Dictionary<string, object> myPara = new Dictionary<string, object>();
myPara.Add("#institutionId", ddlInstitution.SelectedItem.Value);
SqlDataReader dr = myCrud.getDrPassSql(mySql, myPara);
ddlTemplate.DataTextField = "DocName";
ddlTemplate.DataValueField = "internDocId";
ddlTemplate.DataSource = dr;
ddlTemplate.DataBind();
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
CRUD myCrud = new CRUD();
string mySql = #"select* from intern
where institutionId = #institutionId"/*+#"select internDocId,DocName from internDoc where internDocId=internDocId"*/;
Dictionary<string, object> myPara = new Dictionary<string, object>();
myPara.Add("#institutionId", ddlInstitution.SelectedItem.Value);
//myPara.AsEnumerable(#"internDocId");
SqlDataReader dr = myCrud.getDrPassSql(mySql, myPara);
gvData.DataSource = dr;
gvData.DataBind();
}
protected void btnGenerateTemplate_Click(object sender, EventArgs e)
{
wordT();
}
private static DataTable GetRecipients()
{
//Creates new DataTable instance.
DataTable table = new DataTable();
//Loads the database.
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + #"../../CustomerDetails.mdb");
//Opens the database connection.
conn.Open();
OleDbDataAdapter adapter = new OleDbDataAdapter("Select * from intern", conn);
//Gets the data from the database.
adapter.Fill(table);
//Releases the memory occupied by database connection.
adapter.Dispose();
conn.Close();
return table;
}
public void wordT()
{
for (int i = 0; i <= gvData.Rows.Count - 1; i++)
{
String internId = gvData.Rows[i].Cells[0].Text;
String fullName = gvData.Rows[i].Cells[7].Text;
String cell = gvData.Rows[i].Cells[8].Text;
String email = gvData.Rows[i].Cells[9].Text;
Syncfusion.DocIO.DLS.WordDocument document = new Syncfusion.DocIO.DLS.WordDocument(Server.MapPath(getPath()));
//Deleting null fields
document.MailMerge.RemoveEmptyParagraphs = true;
string[] fieldNames = new string[] { "fullName", "internId", "email", "cell" };
string[] fieldValues = new string[] { fullName, internId, email, cell };
// mail merge
document.MailMerge.Execute(fieldNames, fieldValues);
//Saves
document.Save(Server.MapPath("~/myDoc/" + email + ".docx"));
document.Close();
}
// pass message to user notifying of successfull operation
lblOutput.Text = "Word Doc output generated successfully!";
}
public string getPath()
{
DirectoryInfo di = new DirectoryInfo(#"C:\projects\unSupervisorApp\Uploads\");
foreach (var d in di.EnumerateDirectories())
{
foreach (var fi in d.EnumerateFileSystemInfos())
{
if (fi.Name == (ddlTemplate.DataTextField))
{
return fi.FullName.Replace(fi.Name, "");
}
}
}
return di.FullName;
}
}//cls
the problem:
1-'C:/projects/unSupervisorApp/Uploads/' is a physical path but was expected to be a virtual path.
2- and sometime it gives me that it i can not find the file in EnumerateDirectories.
but i get the first one the most.
getFile
getPath
path of folder + ddlselectedItem.text
I have a dropdownlist with few items which bind in code behind. I populate dropdownlist from below query.
Select ID, Name, IsGroup from TempTable
i set DataTextField = "Name" and DataValueField = "ID"
Now i want to disable some items based on "IsGroup" value in DataBound event. How can i access this "IsGroup" column.
For Each item As ListItem In dd.Items
If (What i will compare here = "N") Then
item.Attributes.Add("disabled", "disabled")
End If
Next
Regards
protected void Page_Load(object sender, EventArgs e)
{
var data = GetData();
List<ListItem> items = new List<ListItem>();
foreach (DataRow row in data.Rows)
{
var item = new ListItem()
{
Value = row["Id"].ToString(),
Text = row["Name"].ToString()
};
if (row["IsGroup"].ToString() != "N")
{
item.Attributes.Add("disabled", "disabled");
}
items.Add(item);
}
this.DropDownList1.Items.AddRange(items.ToArray());
}
ref: make drop down list item unselectable
You are doing 2 activities
Fetching data from the database
populating the list item and attaching property/properties to the list item element
Method 1 : Primarily to understand the different operations involved.
class SurroundingClass
{
class Example1
{
public int ID { get; set; }
public string Name { get; set; }
public string IsGroup { get; set; }
}
public void PopulateExample1()
{
// Separate Sections for Database and Dropdown Manipulation
// Database operation
var cs = System.Configuration.ConfigurationManager.ConnectionStrings("CS").ConnectionString;
string sql = "Select ID, Name, IsGroup from TempTable";
SqlConnection conn = new SqlConnection(cs);
SqlCommand cmd = new SqlCommand(sql, conn);
var dr = cmd.ExecuteReader();
List<Example1> e1 = new List<Example1>();
while (dr.Read)
{
var e = new Example1();
e.ID = dr.GetInt32(0);
e.Name = dr.GetString(1);
e.IsGroup = dr.GetString(2);
e1.Add(e);
}
dr.Close();
conn.Close();
// Populate Dropdown
foreach (var i in e1)
{
var li = new ListItem(i.Name, i.ID);
if (i.IsGroup == "Y")
li.Attributes.Add("disabled", "disabled");
ddlExample1.Items.Add(li);
}
}
}
Method 2 : Squeezing the operations in Method 1 together
public void PopulateExample2()
{
// Database Operation and Dropdown Manipulation together
var cs = System.Configuration.ConfigurationManager.ConnectionStrings("CS").ConnectionString;
string sql = "Select ID, Name, IsGroup from TempTable";
SqlConnection conn = new SqlConnection(cs);
SqlCommand cmd = new SqlCommand(sql, conn);
var dr = cmd.ExecuteReader();
while (dr.Read)
{
var li = new ListItem(dr.GetString(1), dr.GetInt32(0));
if (dr.GetString(2) == "Y")
li.Attributes.Add("disabled", "disabled");
ddlExample2.Items.Add(li);
}
dr.Close();
conn.Close();
}
Please note that there can be several variations to the solution, this being only one of them.
I have been given some c# code and have been asked to create a markup (.aspx) file that would go along with it.
I am not asking for help to write the code, but instead, how to go about it.
Here is the code:
public partial class search : Page
{
protected override void OnLoad(EventArgs e)
{
int defaultCategory;
try
{
defaultCategory = Int32.Parse(Request.QueryString["CategoryId"]);
}
catch (Exception ex)
{
defaultCategory = -1;
}
Results.DataSource = GetResults(defaultCategory);
Results.DataBind();
if (!Page.IsPostBack)
{
CategoryList.DataSource = GetCategories();
CategoryList.DataTextField = "Name";
CategoryList.DataValueField = "Id";
CategoryList.DataBind();
CategoryList.Items.Insert(0, new ListItem("All", "-1"));
CategoryList.SelectedIndex = CategoryList.Items.IndexOf(CategoryList.Items.FindByValue(defaultCategory.ToString()));
base.OnLoad(e);
}
}
private void Search_Click(object sender, EventArgs e)
{
Results.DataSource = GetResults(Convert.ToInt32(CategoryList.SelectedValue));
Results.DataBind();
}
private DataTable GetCategories()
{
if (Cache["AllCategories"] != null)
{
return (DataTable) Cache["AllCategories"];
}
SqlConnection connection = new SqlConnection("Data Source=DB;Initial Catalog=Store;User Id=User;Password=PW;");
string sql = string.Format("SELECT * From Categories");
SqlCommand command = new SqlCommand(sql, connection);
SqlDataAdapter da = new SqlDataAdapter(command);
DataTable dt = new DataTable();
da.Fill(dt);
Cache.Insert("AllCategories", dt, null, DateTime.Now.AddHours(1), System.Web.Caching.Cache.NoSlidingExpiration);
connection.Dispose();
return dt;
}
private DataTable GetResults(int categoryId)
{
SqlConnection connection = new SqlConnection("Data Source=DB;Initial Catalog=Store;User Id=User;Password=PW;");
string sql = string.Format("SELECT * FROM Products P INNER JOIN Categories C on P.CategoryId = C.Id WHERE C.Id = {0} OR {0} = -1", categoryId);
SqlCommand command = new SqlCommand(sql, connection);
SqlDataAdapter da = new SqlDataAdapter(command);
DataTable dt = new DataTable();
da.Fill(dt);
connection.Dispose();
return dt;
}
}
EDIT
In the above code, what is the Results object and is the CategoryList just a listbox?
As Nilesh said this seems like a search page, You can possibly try creating the a Webform using Visual studio which is just drag and drop controls into canvas and that will create the mark up for the controls in the code window.
This code behind seems to be doing the following,
On page load at Get request (when its !Page.IsPostBack) page is going to get categories using GetCategories() and fill the drop down list "CategoryList" with all category names (default selected one being the defaultcategory ID from query string).
The search button takes the dropdown's selected value and calls the GetResults() to get data table to fill the grid view "Results". So you need 3 controls (Dropdown list, Button, Gridview) in the webform with these names..
I have DAL function as
public DataTable executeSelectQuery(String _query, SqlParameter[] sqlParameter)
{
SqlCommand myCommand = new SqlCommand();
DataTable dataTable = new DataTable();
dataTable = null;
DataSet ds = new DataSet();
try
{
myCommand.Connection = openConnection();
myCommand.CommandText = _query;
myCommand.Parameters.AddRange(sqlParameter);
myCommand.ExecuteNonQuery();
myAdapter.SelectCommand = myCommand;
myAdapter.Fill(ds);
dataTable = ds.Tables[0];
}
catch (SqlException e)
{
Console.Write("Error - Connection.executeSelectQuery - Query:
" + _query + " \nException: " + e.StackTrace.ToString());
return null;
}
finally
{
}
return dataTable;
}
My button click
public void save_click(object sender,EventArgs e)
{
try
{
string query = "Insert into customer_master(customer_title,customer_name)values(#parameter1,#parameter2)";
SqlParameter[] sqlparam = new SqlParameter[2];
sqlparam[0] = new SqlParameter("#parameter1", SqlDbType.VarChar, 50);
sqlparam[0].Value = ddl_title.SelectedValue;
sqlparam[1] = new SqlParameter("#parameter2", SqlDbType.VarChar, 50);
sqlparam[1].Value = txt_group_name.Text;
string id = ms.insert(query, sqlparam);
catch(Exception ex)
{
throw ex;
}
}
I want the button click function values to passed not as sqlparameter but as sql command object.How to do this with sqlcommand object instead of sqlparameter.
Why do you want to pass around SqlCommand objects?? I wouldn't consider that an improvement of your current code - in the contrary!
Your UI code should really only pass values to the DAL function - just a List<int> or two strings or something. The DAL should do all the database-related stuff like creating SqlCommand and SqlParameters
So in your case here, I would have a method InsertCustomer on your DAL something like this:
public void InsertCustomer(string customerName, string customerTitle)
{
.... // do all the DB stuff here - create SqlCommand, fill in SqlParameter,
// execute the query
}
and your UI code should call this like this:
MyDAL dal = new MyDAL();
dal.InsertCustomer(txt_group_name.Text, ddl_title.SelectedValue);
There should be no trace whatsoever of ADO.NET classes or function in your UI code layer! So don't create SqlCommand or even SqlParameter in your UI layer - encapsulate this in the DAL layer! That what it's for!
I have 2 arraylists. One is principleList which contains integer values that denotes roles (Admin, Project Manager etc.). Second is codeList which contains the various codes (e.g. AddUserProfile) for which I want to get permissions. I have a stored procedure "AllowedToPerformFunction" that returns allowed =0 or 1 depending on if a role can perform a code.
I am having trouble with the logic for this since I have multiple ids and multiple codes. For each id, I need to call the stored procedure with each code and store this.
I am trying to store permissions in a hashtable for various roles such as Admin, Project Manager. So for example for Admin i would need to store:
Admin (id =1)
code = "AddUser",allowed =1
code="AddProject",allowed=0
hashtable format (key,value) = (1, AddUser-1), (1, AddProject-0)
Here is my code that isn't working:
protected void Page_Load(object sender, EventArgs e)
{
getPermissions();
}
void getPermissions()
{
using (SqlConnection conn = new SqlConnection("GoalFishConnectionString")){conn.Open();
ArrayList idList = getPrincipleIds();
ArrayList codeList = getCodes();
ArrayList allowList = new ArrayList();
for (int i = 0; i < idList.Count; i++)
{
MessageBox.Show(idList[i].ToString());
for (int j = 0; j < codeList.Count; j++)
{
MessageBox.Show(codeList[j].ToString());
SqlCommand command2 = new SqlCommand("AllowedToPerformFunction", conn);
command2.CommandType = CommandType.StoredProcedure;
command2.Parameters.Clear();
command2.Parameters.Add("#principalID", SqlDbType.Int).Value = idList[i];
command2.Parameters.Add("#contextID", SqlDbType.Int).Value = idList[i];
command2.Parameters.Add("#roleCode", SqlDbType.VarChar).Value = codeList[j];
command2.Parameters.Add("#allowed", SqlDbType.Int);
command2.Parameters["#allowed"].Direction = ParameterDirection.Output;
command2.ExecuteNonQuery();
int allowed = (int)command2.Parameters["#allowed"].Value;
allowList.Add(command2.Parameters["#allowed"].Value);
}
}}}
ArrayList getPrincipleIds()
{
ArrayList principleList = new ArrayList();
using (SqlConnection conn = new SqlConnection("GoalFishConnectionString")){
conn.Open();
SqlCommand cmd = new SqlCommand("GetPrinciples", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
principleList.Add(rdr["unit_id"]);
}
rdr.Close();
}
return principleList;
}
ArrayList getCodes()
{
ArrayList codesList = new ArrayList();
using (SqlConnection conn = new SqlConnection("GoalFishConnectionString")){
conn.Open();
SqlCommand command = new SqlCommand("GetCodes", conn);
command.CommandType = CommandType.StoredProcedure;
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
codesList.Add(reader["Code"]);
//MessageBox.Show(reader["Code"].ToString());
}
reader.Close();
}
}
return codesList;
}
Any advice or help with this would greatly be appreciated.
Why not make a class like this and store it in the session? This way you only have to worry about permissions for one user (unless a user can be admin & Project Manager at the same time)
public class LoginUser
{
public loginUser
{
this.Permission = LoadAllPermissions()
}
public string Role { get; set; }
public Dictionary<integer, string> Permission { get; set; }
}