I created a method that receives an unspecified amount of dictionaries parameters and scans the content of all of them but the same is not covered, it gives error in the first or second foreach, depending on what I fix. Consegundo'm not fix this problem. How could I make this work paraque.
I get the params dictionary and I want to go through the contents of each.
The code that I follow below:
public String getQuerySelectInner(String TABELA, params Dictionary<String, String> dictionaries)
{
String sql = "SELECT ";
foreach (Object dictionary in dictionaries)
{
foreach (var word in dictionary)
{
sql += word.Key + ",";
}
}
sql = sql.Remove(sql.Length - 1);
sql += " from " + TABELA + " WHERE situacao = 'ATIVO' ";
return sql;
}
Your code doesn't even compile. Are you coding using notepad or an actual IDE?
Anyhow, if you add brackets for your params and change your outer foreach to a var rather than casting to an Object it compiles. Does that help to give you what you want?
public String getQuerySelectInner(String TABELA, params Dictionary<String, String>[] dictionaries)
{
String sql = "SELECT ";
foreach (var dictionary in dictionaries)
{
foreach (var word in dictionary)
{
sql += word.Key + ",";
}
}
sql = sql.Remove(sql.Length - 1);
sql += " from " + TABELA + " WHERE situacao = 'ATIVO' ";
return sql;
}
To further improve things a bit you could use string.join instead of your inner loop: sql += string.Join(",", dictionary.Keys); which means you don't need to remove the extra comma after.
Related
I have a function called "CreateReportForEachCompany" as following:
protected Dictionary<int, List<ReportObject>> CreateReportForEachCompany()
{
try
{
Dictionary<int, List<ReportObject>> dict = new Dictionary<int, List<ReportObject>>();
EnvironmentVariable.setEnvId((int)environmentEnum.mll);
//bakashot_tarif is a VIEW not a TABLE
DataTable dt = GeneralDbExecuterService.executeSqlSelectDataScript("select * from bakashot_tarif");
foreach (DataRow dr in dt.Rows)
{
var reportRow = FillObjectWithValues(dr);
int company_Id = dr.Field<int>("company_Id");
CreateDictionaryPairIfNotExist(dict, company_Id);
dict[company_Id].Add(reportRow);
}
return dict;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
now lets say I invoked it that way and got myself a dictionary with keys/values as needed.
var dictionary = CreateReportForEachCompany();
now.. I have another function named:
CreateCsvForEachCompany(Dictionary<int, List<ReportObject>> dict)
that TAKES the dictionary as parameter and creates few csvs based on the dictionary keys..
now those two functions above are executed on button click as following:
protected void ExecuteProgram(object sender, EventArgs e)
{
var dictionary = CreateReportForEachCompany();
CreateCsvForEachCompany(dictionary);
}
after that, I have a function named TransferSftpOnClick which meant to transfer file via SFTP (secure file transfer protocol ) into a designated location in the server:
void TransferSftpOnClick(Dictionary<int, List<ReportObject>> dict)
{
EnvironmentVariable.SetSubject(EnvironmentVariable.appSubjectEnum.btl);
string systemId = "MLL";
string fileType = "HIYUV-CHEVRA";
string chargeMonth = DateTime.Now.ToString("yyyyMM");
var fileCreationDate = DateTime.Now.ToString("yyyyMMdd");
string fileCreationTime = DateTime.Now.ToString("HHmmss");
string subject = EnvironmentVariable.appSubjectEnum.btl.ToString().ToUpper();
string location = EnvironmentVariable.getLocalFilePath() + #"\";
foreach (KeyValuePair<int, List<ReportObject>> entry in dict)
{
FtpUtil ftp = new FtpUtil();
int key = entry.Key;
string fileName = systemId + "-" + fileType + "-" + String.Format("{0:00000}", key) + "-" + chargeMonth + "-" + fileCreationDate + "-" + fileCreationTime + ".CSV";
**ftp.saveFileToFtp(location, key.ToString(), fileName, subject);**
}
}
I want my function to recognize the dictionary that is executed in function "ExecuteProgram()"
And I want to trigger onClick on TransferSftpOnClick that will just transfer me the files to the designated location.
how can I achieve that? is it even worth doing?
or should I just do this:
FtpUtil ftp = new FtpUtil();
ftp.saveFileToFtp(location, key.ToString(), fileName, subject);
under the CreateCsvPerCompany to avoid that mess?
hope I was clear, thanks
i'm reading a file with 10002 lines, in each line there is a name that I want to compare with a single string, and if this string is the same, i want to add the string file to a listbox, I'm using the FILE.READLINE and then add each line to a list then I use .CONTAINS method and doesnt works also with == but that doesn work either...Any suggestions?
//This is my code:
foreach (string h in Directory.EnumerateFiles(NomDirec, "resume*"))
{
this.listBox1.Items.Add(h);
//Read Lines here and add them to a list and a listbox
var NombreLinea = File.ReadLines(h);
foreach (var item in NombreLinea)
{
NombreAbuscar.Add(item).Remove(item.IndexOf(":"));
this.listBox3.Items.Add(item);
}
//Here I want to add this file only if "NombreCompleto" is present in my resume file.
foreach (string t in Directory.EnumerateFiles(NomDirec, "ESSD1*"))
{
string[] Nombre = File.ReadLines(t).ElementAtOrDefault(6).Split(':');
string[] ApellidoPat = File.ReadLines(t).ElementAtOrDefault(7).Split(':');
string[] ApellidoMat = File.ReadLines(t).ElementAtOrDefault(8).Split(':');
string NombreCompleto = ApellidoPat[1] + ApellidoMat[1] + "," + " " + Nombre[1] + " " + ":";
foreach (var item in NombreAbuscar)
{
if (NombreCompleto == item)
{
this.listBox1.Items.Add(t);
break;
}
}
}
Could be a way to only read the a certain part of the line and add it to my listbox??
The following piece of code achives the desired results, but performance is extremely slow:
SearchResultCollection absaUsers = ABSAds.FindAll();
SearchResultCollection srcUsers = ds.FindAll();
foreach (SearchResult users in srcUsers)
{
string cn = users.Properties["cn"][0].ToString();
string sn = users.Properties["sn"][0].ToString();
string userID = users.Properties["uid"][0].ToString();
string description = users.Properties["PersonnelAreaDesc"][0].ToString();
string jobCodeID = users.Properties["JobcodeID"][0].ToString();
string CostCentreID = users.Properties["costCentreID"][0].ToString();
string CostCentreDescription = users.Properties["CostCentreDescription"][0].ToString();
string givenName = users.Properties["givenName"][0].ToString();
string employmentStatus = users.Properties["EmploymentStatus"][0].ToString();
string EmploymentStatusDescription = users.Properties["EmploymentStatusDescription"][0].ToString();
foreach (SearchResult absaUser in absaUsers)
{
string absaUID = absaUser.Properties["uid"][0].ToString();
string absaEmploymentStatus = absaUser.Properties["EmploymentStatus"][0].ToString();
string absaEmploymentStatusDescription = absaUser.Properties["EmploymentStatusDescription"][0].ToString();
string absaEmployeeNumber = absaUser.Properties["employeeNumber"][0].ToString();
if (absaUID == cn && absaEmployeeNumber==userID)
{
Console.WriteLine("User Record Found:" + cn);
sw.WriteLine("Modify" + "," + cn + "," + description + "," + userID + "," + givenName + "," + sn + "," + jobCodeID + "," + CostCentreID + "," + CostCentreDescription + "," + sn + "," + cn + "," + employmentStatus + "," + EmploymentStatusDescription);
sw.Flush();
break;
}
}
}
It loops through 2 collections and mtaches the outer loops attributes with the inner's. Any suggestions on how I can optimise the performance?
It would be faster if you extracted all the absaUID values to a lookup first:
var lookup = absaUsers.Cast<SearchResult>()
.ToLookup(x => x.Properties["uid"][0].ToString());
Then you can just use:
foreach (SearchResult users in srcUsers)
{
string cn = users.Properties["cn"][0].ToString();
foreach (SearchResult matches in lookup[cn])
{
...
}
}
You haven't shown how absaUsers is defined - if it's a LINQ query expression, then it could be that your existing code will be going to the database on every iteration at the moment - whereas the above won't. On the other hand, if srcUsers is also a LINQ query expression talking to a database, you should consider doing all the matching at the database using a join instead.
you could use LINQ join, some examples are here, I'm assuming whoever built it into .NET found a pretty optimal way of doing that, and then loop through that. on a sidenote: what are your collection types? please add their declaration to the code snippet.
Use Lamda expressions:
Below is the sample one , You can optizime this to another level.
List<SearchResult> allResultGroups=new List<SearchResult>();
foreach (SearchResult absaUser in absaUsers)
{
resultGroups = srcUsers.Where(g => g.cn == absaUser.absaUID && absaUser.absaEmployeeNumber==g.userID ).ToList();
}
I have the following function:
private string ParseJson(dynamic q)
{
string returnJSON = "[{ \"type\" : \"pie\", \"name\" : \"Campaigns\", \"data\" : [ ";
foreach (var grp in q)
{
double currCount = grp.Count();
if (grp.Key != null)
returnJSON += "['" + grp.Key + "', " + currCount + "],";
else
returnJSON += "['none', " + currCount + "],";
}
returnJSON = returnJSON.Substring(0, returnJSON.Length - 1);
returnJSON += "]}]";
return returnJSON;
}
I call it from methods like this one:
public string GetCampaignData()
{
PaymentModelDataContext db = new PaymentModelDataContext();
var q = from Event in db.TrackingEvents
group Event by Event.campaignID;
return ParseJson(q);
}
I use q for several different queries, all grouping data.
The problem is that the runtime can't bind a type to q for some reason. Is this a proper use of dynamic? Is there a different way to do this?
The problem is Count() is an extension method off of IEnumerable<T>, as such it can't be called from dynamic (because it's not a true method of the class).
Your variable grp is also dynamic because it results from an expression on dynamic variable q:
foreach (var grp in q)
Since we can't call extension methods off of dynamic (again, they aren't true members of the class), we need to explicitly call the extension method instead off the Enumerable static class. So change your code to:
double currCount = Enumerable.Count(grp);
And you'll see it work properly for the Count(), if you want to really use dynamic.
That said, I do agree with #John's comment that you should consider changing this to a non-dynamic. Actually, what your method would accept would be an IEnumerable> like so:
private string ParseJson<TKey,TValue>(IEnumerable<IGrouping<TKey,TValue>> q)
{
string returnJSON = "[{ \"type\" : \"pie\", \"name\" : \"Campaigns\", \"data\" : [ ";
foreach (var grp in q)
{
double currCount = grp.Count();
if (grp.Key != null)
returnJSON += "['" + grp.Key + "', " + currCount + "],";
else
returnJSON += "['none', " + currCount + "],";
}
returnJSON = returnJSON.Substring(0, returnJSON.Length - 1);
returnJSON += "]}]";
return returnJSON;
}
You can also make the parameter type non-generic specific to your usage if you like. But this would work with all groupings...
Alright so I've looked hard but I couldn't seem to find answer to my problem. There must be a problem in my code and it would be really helpful if someone could look at it for me.
Dictionary<string, string> keylist = new Dictionary<string, string>();
if (intext.Contains("addkey") && intext.Contains("def"))
{
string[] keywords = intext.Split(' ');
string key1 = keywords[1];
string def2 = keywords[3];
string fkey = key1.Replace("_", " ");
string fdef = def2.Replace("_", " ");
keylist.Add(fkey, fdef);
say("Phrase '" + fkey + "' added with response '" + fdef + "'");
say("Your Dictionary contains " + keylist.Count.ToString() + " word(s).");
//////////////////////////////
}
All I want it to do is take the input in the form of "addkey key_here def definition_here" and add it to the dictionary. I added the counting part for debugging purposes and it always says I only have 1 word in the dictionary no matter how many I have added. You can probably tell I'm new so please be gentle. Thanks
Dictionary<string, string> keylist = new Dictionary<string, string>();
I'm assuming that this function is called whenever the user enters some sort of command (e.g. from the command line, when they click a button, etc.). If this is the case, you need to have your keylist dictionary at a higher level (as an instance variable, for example). The way the code is now, every time the function is called a new dictionary is created and the key is added to it; this is why there's only one.
At the risk of misjudging or oversimplifying your problem, just moving the line I quoted above outside of the function body should help.
In the code as given you are recreating the dictionary every time you run it.
Dictionary<string, string> keylist = new Dictionary<string, string>();
Reinitializes the variable keylist to an empty dictionary.
Instead try moving that line outside of the function. Since you are using winforms, you can create a class level variable, something like this:
public partial class Form1 : Form
{
Dictionary<string, string> keylist = new Dictionary<string, string>();
public Form1()
{
InitializeComponent();
}
public void YourFunction(string intext)
{
if (intext.Contains("addkey") && intext.Contains("def"))
{
string[] keywords = intext.Split(' ');
string key1 = keywords[1];
string def2 = keywords[3];
string fkey = key1.Replace("_", " ");
string fdef = def2.Replace("_", " ");
keylist.Add(fkey, fdef);
say("Phrase '" + fkey + "' added with response '" + fdef + "'");
say("Your Dictionary contains " + keylist.Count.ToString() + " word(s).");
}
}
}
You need to loop through the if (intext.Contains...{} block or it only runs once. If you are looping through it and only getting one entry in the Dictionary, it's because you keep reassigning it within the scope in a scenario such as:
while(true) {
Dictionary<string, string> keylist = new Dictionary<string,string>();
//...
}
So you'll need to move it outside, if that's your case.
I'm not sure exactly what your input string is or how you need to use it, though I think you're looking to split the input string and loop through along this line...
private Dictionary<string, string> GetData(string intext)
{
Dictionary<string, string> keylist = new Dictionary<string, string>();
string[] keywords = intext.Split(' ');
foreach (string s in keywords)
{
if (s.Contains("addkey") && s.Contains("def"))
{
string fkey = key1.Replace("_", " ");
string fdef = def2.Replace("_", " ");
keylist.Add(fkey, fdef);
say("Phrase '" + fkey + "' added with response '" + fdef + "'");
say("Your Dictionary contains " + keylist.Count.ToString() + " word(s).");
}
}
return keylist;
}