how to remove the extra AND from the loop - c#

foreach (string word in allTheseWords)
{
allTheseStringsWhereClause = allTheseStringsWhereClause +
" report=" +
word +
" AND ";
}
The problem is after the loop, the SQL clause has an extra AND at the end of it.
How do I fix this?

you can alternatively use LINQ
string _final = string.Join(" AND ", (allTheseWords.Select(x => "report=" + x)));

By inserting user input into a sql where clause you are introducing a vector for a SQL Injection Attack. Do no use this approach. Basically you want to use SQL Parameters.
where report in #allTheseWords
See http://en.wikipedia.org/wiki/SQL_injection
EDIT
See the answer with the most votes in Parameterize an SQL IN clause for how to really do parameterised in query.

This kind of question is very common and here's the proof.
Delete last char of string
How to delete last character in a string in C#?
Finding the last index of an array
But here my simple solution
string[] allTheseWords = { "try", "test", "let" };
string whereLine = string.Empty;
foreach (var item in allTheseWords)
whereLine += "report = " + item.ToString() + " and ";
string final = whereLine.Remove(whereLine.Length - 5);
Console.WriteLine(final);
Console.ReadLine();

A simple way would be to add a bogus always-true clause (and move the AND):
string allTheseStringsWhereClause = "WHERE 1=1";
foreach (string word in allTheseWords)
{
allTheseStringsWhereClause = allTheseStringsWhereClause +
" AND report=" +
word;
}

You don't need LINQ, just use Join:
string whereClause = " report=" + String.Join(" AND report=", allTheseWords);

The best way to do this without hard coding a substring method is to try an Aggregate LINQ query
var result = allTheseWords.Aggregate(allTheseStringsWhereClause, (current, word) => current + " report=" + word + " AND ");

Easy. You just need to do allTheseStringsWhereClause.substr(0,-4) and that's it!

Related

Put single quote in each values inside a string in C#

I am trying to put a single quote in each values in a string that is separated by comma to include it in an SQL query (ex. "AND STAT IN ('11', '12'). Please help me if you have any ideas.
Sample data: string sStatus = "10,20,30,40";
I have already tried splitting each of the values.
if (!String.IsNullOrEmpty(sStatus))
{
string[] sStatList = sStatus.Split(',');
foreach (string p in sStatList)
{
}
sFilter = String.Format(" AND STAT IN ({0})", sStatList);
}
You can use Select().
string[] sStatList = sStatus.Split(',');
var res = string.Join(",", sStatList.Select(s => $"'{s}'"));
This requires using System.Linq;.
try this:
string[] sStatList = sStatus.Split(',');
string sFilter= "";
foreach (string p in sStatList)
{
sFilter = sFilter+ ("'" + p + "',");
}
if(sFilter.EndsWith(","))
{
sFilter = sFilter.Substring(0,sFilter.Length-1);
}
sFilter = " AND STAT IN (" + sFilter + ")";
#oika's answer is on the right track but it's not quite right for what you're trying to do. However Select is the answer here... like this though:
You'll need to add a reference to Linq:
using System.Linq;
Then
var sStatuses = sStatus.Split(',');
var parsedsStatuses = string.Join(",", sStatuses.Select(x => $"'{x}'"));
var sql = $"AND STAT IN ({ parsedsStatuses })";
Of course you do want to be careful doing this, as it opens up a vulnerability for SQL Injection.
You can either use the string.Join like this:
var status = "10,20,30,40";
if (!string.IsNullOrEmpty(status))
{
var sStatList = status.Split(',');
filter = $"'{string.Join("','", sStatList)}'";
}
Another option you have, would be to use the string.Replace:
var status = "10,20,30,40";
filter = $"'{status.Replace(",","','")}'";
Either way, you need to validate the input to avoid SQL Injection. Consider following:
status = "10,20,30');/*,*/ DROP TABLE Users;//";
Dapper for example supports this directly:}
var sql = "SELECT * FROM table WHERE Id IN #ids"
var results = connection.Query(sql, status.Split(','));
and there are alternative orms that will handle parameterisation.
As a side note: avoid using the Hungarian notation in C# as microsoft also recommends. The Hungarian notation where you specify the variable type using a prefix is useless information and adds noise, especially VS and VS Code will tell you the type anyway.

Extracting field values from IEnumerable

I have a variable results which holds ResultView as shown below:
In turn StoryQ.Execution.Result IEnumerable will hold values:
I need to extract text representation like " Story is Story". How can I achieve this. Could anyone help me on this. Thanks
Solution is to use select in conjunction with string format.
.Select( c => new {Story_Prefix_Text = string.Format("{0} {1}" ,c.Prefix, c.Text)})
or without lambda
from currentpath in collection
select new { Story_Prefix_Text = currentpath.Prefix + " " + currentpath.Text };
Answering my own question just in case it would help somebody in future.
The problem was solved by converting IEnumerable to List and then iterating through foreach loop. Code snippet is below:
var textFormat = ((IStepContainer)v).SelfAndAncestors().Reverse().ToList();
foreach (var text in textFormat)
{
var StoryInText = text.Step.Prefix + " " + text.Step.Text;
}

Convert list to string with single quotes

I am trying to create a string from List
This is my code
List<string> SelectedSalesmen = new List<string>();
and I am adding selected salesmen from listBox like this
foreach (ListItem lst in lstBoxSalesmen.Items)
{
if (lst.Selected)
{
SelectedSalesmen.Add(lst.Value);
}
}
finally I am storing that value to a string like this
string SalesManCode = string.Join(",", SelectedSalesmen.ToArray());
But I am getting like this
SLM001,SLM002,SLM003
but I need Output like this
'SLM001','SLM002','SLM003'
Try this:
string SalesManCode = string.Join(",", SelectedSalesmen
.Select(x=>string.Format("'{0}'",x)));
it will wrap all your elements with ' and then join them using , as separator
What about this:
string output = "'" + string.Join("','", SelectedSalesmen) + "'";
Though this'll return '' for an empty input.
Same as the answer from #wudzik but with string interpolation
var salesManCode = string.Join(",", selectedSalesmen.Select(x => $"'{x}'"));
Just use the above one with split like below:
string.Join(",", SelectedSalesmen.Split(',').Select(x => string.Format("'{0}'", x)));
which will give you:
"'SLM001','SLM002','SLM003'"
you can do something like this:
"'" + string.Joing("',", SelectedSalesmen.ToArray() + "'");

quick and simple way to sort this data taken from a tsv and make it distinct as per one of the fields that it contains

I want to know the quickest and simplest way to sort the code shown below. Sorting from newRecord.AppCode would not be suitable as it will change the meaning of the output. So I need to sort every line from string outp. What would be the best way? Also I would like to make every row distinct. I beleive using LINQ would be very quick but I am not that great at it. Help appreciated. So close to getting it done! Note: Data is being pulled from a tsv. Using .net 3.5, visual studio 2008) Will mark answer as soon as I get progress. :)
while ((line = sr.ReadLine()) != null)
{
String[] splitted = line.Split('\t');
appcodes.Add(line);
Records newRecord = new Records();
newRecord.Server = splitted[0];
newRecord.Instance = splitted[1];
newRecord.AppCode = splitted[2];
newRecord.Database = splitted[3];
listrecords.Add(newRecord);
for (int i = 0; i < appcodes.Count(); i++)
{
if (newRecord.AppCode==appcodes[i].ToUpper())
{
String outp = newRecord.AppCode + " " + newRecord.Server + " " + newRecord.Instance + " " + newRecord.Database;
Console.WriteLine(outp);
}
}
}
have lists named Keepers and newkeepers. Was trying to do something like outp.sort() and outp.sort() but it doesnt work in strings. This is how I solved the problem.
Keepers.Add(outp);
Keepers.Sort();
newKeepers = Keepers.Distinct().ToList();
foreach (object o in newKeepers)
{
Console.WriteLine(o);
}
Console.ReadLine();
As you can see, newrecords contain different fields so I wrote a LINQ statement to solve the problem.
var sorted_list = (from r in newrecords
orderby r.AppCode, r.Server, r.Instance, r.Database
select r).Distinct().ToList();
var distinctSortedList = sorted_list.Distinct().ToList();

Procedurally create a dynamic object for Dapper

I've seen many posts about creating ExpandoObject objects and such, but it does not work in my case. I need to create an object like
var someObj = new {
term1 = "someValue",
term2 = "other",
...
};
Basically, we are using Dapper and we need to create a query dynamically, where the WHERE clause is fabricated from a given array of arguments. We are not generalizing queries! It's a single method receiving a variable number of arguments and we need to check OR each value on a single column.
Right now, the only viable solution is to revert and directly use System.Data.SqlClient.SqlConnection, or is there any way to make this work?
Update:
This is what most likely should work, but doesn't :
string inWhere = null;
dynamic inTerms = new ExpandoObject();
IDictionary<string, object> inTermsDict = inTerms;
if (!(string.IsNullOrEmpty(filter.Term) || string.IsNullOrWhiteSpace(filter.Term))) {
inWhere = "(" + string.Join(" OR ", filter.Terms.Select((t, i) => "{0} LIKE #p" + i)) + ")";
int termIndex = 0;
foreach (string term in filter.Terms) {
inTermsDict.Add("p" + (termIndex++), term);
}
}
// ...
var rows = db.Query("SELECT * FROM {table} WHERE {baseCondition}" +
(string.IsNullOrEmpty(inWhere) ? "" : string.Format(" AND " + inWhere, "columnName")),
inTerms as object);
Just to answer my own question, as we found the proper solution earlier today.
Simply put, we found the IDynamicParameters And this class simply solves everything, acting as a Dictionary.
var inTerms = new Dapper.DynamicParameters();
inTerms.Add("#p" + (termIndex++), somveValue);
Everyone's happy!

Categories

Resources