I am using linq to query data.
But I want it return uppercase field.
Below is my code, how to transfer all field to uppercase?
public List<dynamic> QueryToList(string connStr, string sql)
{
using (OracleConnection conn = new OracleConnection(connStr))
{
conn.Open();
var results= conn.Query(sql).ToList();
conn.Close();
return results; //For now, it would return all fields into lower case.
}
}
Edit:
Thanks for #Alen.Toma, I use the code below and it return the result I want.
public List <dynamic> QueryToList(string connStr, string sql)
{
conn.Open();
var results = conn.Query(sql);
conn.Close();
var valueResult = new List<dynamic>();
foreach (dynamic item in results)
{
var dicItem = item as IDictionary<string, object>;
var x = new ExpandoObject();
foreach (var i in dicItem.Keys)
{
((ICollection<KeyValuePair<string, object>>)x).Add(new KeyValuePair<string, object>(i.ToUpper(), dicItem[i]));
}
valueResult.Add(x);
}
return valueResult;
}
Well I agree with #Panagiotis Kanavos, even better is to convert the data to an class object.
Incase you still want to do it as such
Here is an example.
public List <dynamic> QueryToList(string connStr, string sql) {
var valueResult = new List <dynamic> ();
using(OracleConnection conn = new OracleConnection(connStr)) {
conn.Open();
var results = conn.Query(sql).ToList();
conn.Close();
foreach(var item in results) {
var dicItem = item as Dictionary <string,object> ;
var x = new ExpandoObject();
forEach(var i in dicItem.Keys)
((ICollection<KeyValuePair <string, object>>)x).Add(i.ToUpper(), dicItem[i]);
valueResult.Add(x);
}
return valueResult;
}
}
Related
I would like my code to return a value but it returns me:
System.Collections.Generic.List`1[Dapper.SqlMapper+DapperRow]
I can't solve and make a right output process.
public static string Test()
{
using (IDbConnection cnn = new SQLiteConnection(LoadConnectionString()))
{
var vartest = cnn.Query("select grado from utenti where id='10'");
//var result = output.ToDictionary(row => (string)row.Grado, row => (string)row.Nome ) ; (commento)
//Console.WriteLine(vartest);
cnn.Close();
return vartest.ToString();
}
}
Query and Query<T> return multiple rows; Query is for dynamic rows; Query<T> is for typed rows. There are QueryFirst[<T>] and QuerySingle[<T>] for single rows.
If you're after a single value of a known type, then perhaps:
var vartest = cnn.QuerySingle<string>("select grado from utenti where id='10'");
if you mean your return vartest.ToString(); is returning you the string "System.Collections.Generic.List`1[Dapper.SqlMapper+DapperRow]" it is because your vartest is a list of items, you need to .ToString the item in the list
public static string ManagerFindid()
{
using (IDbConnection cnn = new SQLiteConnection(LoadConnectionString()))
{
var select = cnn.Query("select id from utenti");
if (select.Any())
{
return select[0].ToString();
// or do something with all the items in your list
foreach(string value in select)
{
//add value into list view
}
}
else
{
//this is hit when there are no items returned from the select query
return "Nothing Returned from Query";
}
}
you could also handle there being multiple items returned from your SQL
foreach(string value in select)
{
//do something with current value
}
I have read some threads that seem to be similar to this but can't find the fix for my issue, I've not used stack overflow much so pls bear with me
I have a while loop using an SqlDataReader which is pulling information from a DB and putting it into a List for Development Requests as below
public ListOfDevelopmentRequestsModel GetDevRequests(List<SelectListItem> evaluators)
{
SqlCommand cmd = new SqlCommand(StoredProcedures.DevRequests.GetDevRequests, Conn);
cmd.CommandType = CommandType.StoredProcedure;
ListOfDevelopmentRequestsModel ListOfDevRequests = new ListOfDevelopmentRequestsModel();
Conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
DateTime requestDate = Convert.ToDateTime(reader["DateCreated"].ToString());
string requestorFirstName = reader["Staff First Name"].ToString();
string requestorLastName = reader["Staff Last Name"].ToString();
string requestorEmailAddress = reader["Staff Email"].ToString();
string solutionName = reader["SolutionName"].ToString();
string solutionDescription = reader["SoultionDescription"].ToString();
string solutionElementName = reader["SolutionElementName"].ToString();
string solutionElementDescription = reader["SolutionElementDescription"].ToString();
string itemToChange = reader["ItemChange"].ToString();
string changeDetails = reader["ChangeDetail"].ToString();
List<SelectListItem> evaluatorList = new List<SelectListItem>(DisplayCurrentEvaluator(evaluators, evaluator));
DevelopmentRequestModel DevRequest = new DevelopmentRequestModel
{
RequestDate = requestDate,
RequestorName = $"{requestorFirstName} {requestorLastName}",
RequestorEmailAddress = requestorEmailAddress,
SolutionName = solutionName,
SolutionDescription = solutionDescription,
SolutionElementName = solutionElementName,
SolutionElementDescription = solutionElementDescription,
ItemToChange = itemToChange,
ChangeDetails = changeDetails,
AccordionHeading = $"{(changeID.PadLeft(4, '0'))} - {requestorFirstName} {requestorLastName} - {itemToChange}"
};
ListOfDevRequests.DevelopmentRequests.Add(DevRequest);
}
Conn.Close();
return ListOfDevRequests;
}
I also have a List for getting Evaluators of the requests
public static List<SelectListItem> GetEvaluators()
{
List<SelectListItem> evaluators = new List<SelectListItem>();
SqlCommand cmd = new SqlCommand(StoredProcedures.DevRequests.GetEvaluators, Conn);
cmd.CommandType = CommandType.StoredProcedure;
Conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
evaluators.Add(
new SelectListItem
{
Text = reader["Staff Name"].ToString(),
Value = reader["Staff Code"].ToString(),
});
}
Conn.Close();
return evaluators;
}
Finally I have a List that will pass the above Evaluators List in and the Evaluator that was pulled from the DB: string evaluator = reader["Evaluator"].ToString(); and will set the default value of the select list based on whether the Evaluator name matches the Text value, and set it as the selected select list item.
public List<SelectListItem> DisplayCurrentEvaluator(List<SelectListItem> evaluators, string evaluator)
{
foreach (var item in evaluators)
{
if (item.Text == evaluator)
{
item.Selected = true;
}
else
{
item.Selected = false;
}
}
return evaluators;
}
The issue is that the first item in the loop has the Evaluator "Bill" and "Bill" is selected, and works fine, however the second item in the loop is "John", and when it sets "John" to selected, it replaces "Bill" as the selected value in the first item with "John"
The code has ended up a mess as I have tried multiple different ways to fix but I'm stumped and would appreciate help.
Sorry if the post is formatted poorly to read, I can try to reformat and provide more information if requested.
Cheers
EDITED CODE:
GetDevRequests()
public ListOfDevelopmentRequestsModel GetDevRequests(List<SelectListItem> evaluators)
{
SqlCommand cmd = new SqlCommand(StoredProcedures.DevRequests.GetDevRequests, Conn);
cmd.CommandType = CommandType.StoredProcedure;
ListOfDevelopmentRequestsModel ListOfDevRequests = new ListOfDevelopmentRequestsModel();
Conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
List<SelectListItem> evaluatorList = new List<SelectListItem>();
while (reader.Read())
{
string changeID = reader["ChangeID"].ToString();
string evaluator = reader["Evaluator"].ToString();
string status = reader["Status"].ToString();
string priority = reader["Priority"].ToString();
string eliteID = reader["RequestorID"].ToString();
DateTime requestDate = Convert.ToDateTime(reader["DateCreated"].ToString());
string requestorFirstName = reader["Staff First Name"].ToString();
string requestorLastName = reader["Staff Last Name"].ToString();
string requestorEmailAddress = reader["Staff Email"].ToString();
string solutionName = reader["SolutionName"].ToString();
string solutionDescription = reader["SoultionDescription"].ToString();
string solutionElementName = reader["SolutionElementName"].ToString();
string solutionElementDescription = reader["SolutionElementDescription"].ToString();
string itemToChange = reader["ItemChange"].ToString();
string changeDetails = reader["ChangeDetail"].ToString();
evaluatorList = DisplayCurrentEvaluator(evaluators, evaluator);
DevelopmentRequestModel DevRequest = new DevelopmentRequestModel
{
ChangeID = (changeID.PadLeft(4, '0')),
Evaluator = evaluator,
Evaluators = evaluatorList,
Status = status,
Priority = priority,
EliteID = eliteID,
RequestDate = requestDate,
RequestorName = $"{requestorFirstName} {requestorLastName}",
RequestorEmailAddress = requestorEmailAddress,
SolutionName = solutionName,
SolutionDescription = solutionDescription,
SolutionElementName = solutionElementName,
SolutionElementDescription = solutionElementDescription,
ItemToChange = itemToChange,
ChangeDetails = changeDetails,
AccordionHeading = $"{(changeID.PadLeft(4, '0'))} - {requestorFirstName} {requestorLastName} - {itemToChange}"
};
ListOfDevRequests.DevelopmentRequests.Add(DevRequest);
}
Conn.Close();
return ListOfDevRequests;
}
DisplayCurrentEvaluator()
public List<SelectListItem> DisplayCurrentEvaluator(List<SelectListItem> selectListItems, string selectListDefaultItem)
{
foreach (var item in selectListItems)
{
item.Selected = item.Text == selectListDefaultItem;
}
return selectListItems;
}
The problem is in this line:
List<SelectListItem> evaluatorList = new List<SelectListItem>(DisplayCurrentEvaluator(evaluators, evaluator));
First, this can also be written as
List<SelectListItem> evaluatorList = DisplayCurrentEvaluator(evaluators, evaluator);
Your DisplayCurrentEvaluator already returns a correct list, so there is no need to copy it into a new one.
But this is a minor point as you don't use that evaluatorList as far as I can see. In every iteration of that while-loop you are creating a new one (which probably isn't what you want) and then you forget about it. I also don't see where evaluator is set, but that is probably in code you didn't show.
So you will need to generate this list once, outside the loop and keep it (probably in a class-level field or property).
And an extra tip, that DisplayCurrentEvaluator method can also be written as
public List<SelectListItem> DisplayCurrentEvaluator(List<SelectListItem> evaluators, string evaluator)
{
foreach (var item in evaluators)
{
item.Selected = item.Text == evaluator;
}
return evaluators;
}
EDIT after code was shown that set evaluator and used the resulting evaluatorList
Your DisplayCurrentEvaluator updates the original evaluators list and returns it. This effectively results in every evaluatorList pointing to the same list, where the last update wins. So make sure you return a new list.
public List<SelectListItem> DisplayCurrentEvaluator(List<SelectListItem> evaluators, string evaluator)
{
var result = new List<SelectListItem>(evaluators.Count);
foreach (var item in evaluators)
{
result.Add(new SelectListItem { Text = item.Text, Value = item.Value, Selected= item.Text == evaluator};
}
return result;
}
Additionally, declare the evaluatorList (only) inside of the loop.
var evaluatorList = DisplayCurrentEvaluator(evaluators, evaluator);
I have method to save all values from table to txt file:
UserDataDBsDataContext dataContext = new UserDataDBsDataContext();
List<UserData> usersL = (from u in dataContext.UserDatas
select u).ToList();
var properties = typeof(UserData).GetProperties();
var userValues = new List<string>();
foreach (var user in usersL)
{
var values = new List<object>();
foreach (var property in properties)
{
object value = property.GetValue(user, null);
values.Add(value);
}
userValues.Add(string.Join(",", values));
}
File.WriteAllLines("my_data.txt", userValues);
Now I have two query and I want to do exactly the same, so I tried to create separate method responsible for looping table values.
Loop Method:
public void loopProp(PropertyInfo[] properites, List<string> addedValues)
{
foreach (var qrl in ...........)
{
var values = new List<object>();
foreach (var property in properites)
{
object value = property.GetValue(qrl, null);
values.Add(value);
}
addedValues.Add(string.Join(",", values));
}
File.WriteAllLines("my_passed_data.txt", addedValues);
}
But I don't know, how to pass query result(ar or ud):
My code:
List<AutoRef> ar = (from a in rjdc.AutoRefs
select a).ToList();
List<UserDataRef> ud = (from u in rjdc.UserDataRefs
select u).ToList();
var propertiesAutoRef = typeof(AutoRef).GetProperties();
var autoValues = new List<string>();
var propertiesUserRef = typeof(UserDataRef).GetProperties();
var userValues = new List<string>();
//loopProp(propertiesAutoRef, autoValues);
//loopProp(propertiesUserRef, userValues);
Answering your concrete question. You should make the method generic and pass the source as IEnumerable<T>:
public void loopProp<T>(IEnumerable<T> source, PropertyInfo[] properites, List<string> addedValues)
{
foreach (var qrl in source)
{
// ...
}
File.WriteAllLines("my_passed_data.txt", addedValues);
}
Usage:
loopProp(ar, propertiesAutoRef, autoValues);
loopProp(ud, propertiesUserRef, userValues);
Probably you should pass the file path argument as well instead of hardcoding it inside the method.
I need to write search based on following criteria:
I need to find all records that match values of
key1 OR key2 OR key 3 values...etc
The number of keys and values is variable
List<KeyValuePair<string, string[]>> filterlist = new List<KeyValuePair<string, string[]>>()
{
new KeyValuePair<string, string[]>("Key1", new []{"jay","bloggs"}),
new KeyValuePair<string, string[]>("Key2", new []{"joe","blog","doe"}),
new KeyValuePair<string, string[]>("Key3", new []{"jon","blog"}),
};
Now my implementation
My current implementation does search but all expressions are "AND" instead of OR. I am not sure how to write it.
public class UserSearcher
{
private List<UserProfile> userProfiles;
public UserSearcher()
{
userProfiles = new List<UserProfile>();
}
public static List<UserProfile> SearchProfiles(List<KeyValuePair<string, string[]>> filterList)
{
var list = new List<UserProfile>();
var query = list.AsQueryable();
// search for each pair inside as or
foreach (KeyValuePair<string, string[]> searchPair in filterList)
{
foreach (string searchString in searchPair.Value)
{
string s = searchString;
// search for each item inside as and (has to contains all search strings
query = query.Where(x => x.PersonName.Contains(s));
}
}
return list = query.ToList();
}
}
The full example except db is:
https://gist.github.com/cpoDesign/acf69bc242ed0755597d
Use Predicate Builder - it works well.
So, if I got it right, you want to get back list of UserProfile where PersonName is inside any string[] of KeyValuePair list.
If so, try with this:
public static List<UserProfile> SearchProfiles(List<KeyValuePair<string, string[]>> filterList)
{
var list = new List<UserProfile>();
return list.Where(profile => filterList.Any(kvp => kvp.Value.Contains(profile.PersonName))).ToList();
}
Test example:
public static Expression<Func<T,bool>>
Or<T>(IEnumerable<Expression<Func<T,bool>>> expList){
ParameterExpression pe = Expression.Parameter(typeof(T));
Expression r = null;
foreach(var exp in expList){
r = r == null ? exp : Expression.Or(r,exp);
}
return Expression.Lambda<Func<T,bool>>(r.Body,pe);
}
var orList = new List<Expression<Func<T,bool>>>();
foreach (KeyValuePair<string, string[]> searchPair in filterList)
{
foreach (string searchString in searchPair.Value)
{
string s = searchString;
// search for each item inside as and
// (has to contains all search strings
orList.Add(x => x.PersonName.Contains(s));
}
}
query = query.Where( Or(expList));
Ive created a Directory Searcher to pull multiple properties from each user.
objSearchADAM = new DirectorySearcher(objADAM);
objSearchADAM.PropertiesToLoad.Add("givenname");
objSearchADAM.PropertiesToLoad.Add("lastlogontimestamp");
ect...
objSearchResults = objSearchADAM.FindAll();
I then enumerate them, and convert the interger8 timestamp to standard date/time, and save to csv file with
List<string> timeProps = new List<string>() { "lastlogontimestamp", "accountexpires", "pwdlastset", "lastlogoff", "lockouttime", "maxstorage", "usnchanged", "usncreated", "usndsalastobjremoved", "usnlastobjrem", "usnsource" };
foreach (SearchResult objResult in objSearchResults)
{
objEntry = objResult.GetDirectoryEntry();
ResultPropertyCollection myResultProp = objResult.Properties;
foreach (string myKey in myResultProp.PropertyNames)
{
foreach (Object myCollection in myResultProp[myKey])
{
Object sample = myCollection;
if (timeProps.Contains(myKey))
{
String times = sample.ToString();
long ft = Int64.Parse(times);
DateTime date;
try
{
date = DateTime.FromFileTime(ft);
}
catch (ArgumentOutOfRangeException ex)
{
date = DateTime.MinValue;
Console.WriteLine("Out of range: " + ft);
Console.WriteLine(ex.ToString());
}
sample = date;
Console.WriteLine("{0}{1}", myKey.PadRight(25), sample);
objWriter.WriteLine("{0}{1}", myKey.PadRight(25), sample);
}
else
{
Console.WriteLine("{0}{1}", myKey.PadRight(25), sample);
objWriter.WriteLine("{0}{1}", myKey.PadRight(25), sample);
}
}
now i need to create an object for each user with the strings from each result that i can put into an SQL command ive built. where the LDAP query to SQL would be givenname = FirstName and lastlogontimestamp = LastLogon and so on.
StringBuilder sb = new StringBuilder();
sb.Append("INSERT INTO activedirectory.dimUserST (FirstName, LastName) VALUES (#FirstName, #LastName)");
loadStagingCommand.Parameters.AddWithValue("#FirstName", FirstName).DbType = DbType.AnsiString;
ect...
loadStagingCommand.CommandText = sb.ToString();
loadStagingCommand.ExecuteNonQuery();
i tried to use IDictionary in my first foreach (similar to code found here http://ideone.com/vChWD ) but couldn't get it to work. I read about IList and reflection, but im not sure how i could incorporate these.
UPDATE
I researched and found ExpandoObjects and attempted to write in code based off of what i saw in here Creating Dynamic Objects
however i run this new code I return "employeenumber System.Collections.Generic.List`1[System.Dynamic.ExpandoObject]"
if(employeeNumber.Contains(myKey))
{
string[] columnNames = { "EmployeeNumber" };
List<string[]> listOfUsers = new List<string[]>();
for (int i = 0; i < 10; i++)
{
listOfUsers.Add(new[] { myKey});
}
var testData = new List<ExpandoObject>();
foreach (string[] columnValue in listOfUsers)
{
dynamic data = new ExpandoObject();
for (int j = 0; j < columnNames.Count(); j++)
{
((IDictionary<String, Object>)data).Add(columnNames[j], listOfUsers[j]);
}
testData.Add(data);
Console.WriteLine("{0}{1}", myKey.PadRight(25), testData);
objWriter.WriteLine("{0}{1}", myKey.PadRight(25), testData);
}
}
I am obviously missing something here and cant seem to wrap my head around what the problem is. I might even be going about this the wrong way. Basically all i need to do is pull users and their properties from Active Directory and put into SQL database tabels. And I've worked out how to do both separately, but I cant figure out how to put it all together.
If the CSV is just being used to cache the results, you could use a Dictionary to store the contents of the search results instead. Separating your code into functions could be helpful:
private static object GetFirstValue(ResultPropertyCollection properties,
string propertyName)
{
var propertyValues = properties[propertyName];
var result = propertyValues.Count == 0 ? null : propertyValues[0];
return result;
}
Then you could either use a dictionary to hold the property values, or you could create a type:
var results = new List<Dictionary<string, object>>();
foreach(SearchResult objResult in objSearchResults)
{
var properties = objResult.Properties;
var propertyDictionary = new Dictionary<string, object> {
{"FirstName", GetFirstValue(properties, "givenname")},
{"LastName", GetFirstValue(properties, "sn")},
{"UserName", GetFirstValue(properties, "samaccountname")},
};
results.Add(propertyDictionary);
}
Now you have a list of property bags.
This could also be a simple LINQ statement:
var results = objSearchResults.OfType<SearchResult>()
.Select(s => s.Properties)
.Select(p => new {
FirstName = (string)GetFirstValue(properties, "givenname"),
LastName = (string)GetFirstValue(properties, "sn"),
UserName = (string)GetValue(properties, "samaccountname"),
AccountExpires = GetDateTimeValue(properties, "accountexpires")
});
Use the dictionaries like this:
foreach(var item in results)
{
var command = new SqlCommand();
...
command.Parameters.AddWithValue("firstName", item["FirstName"]);
...
}