Put single quote in each values inside a string in C# - 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.

Related

How can I use individual words from user input into a SQL 'WHERE CONTANS' query in C#?

This is my first asked question on here, and I can't find the answer so apologies if I've missed it somewhere.
I'm currently building a search function in a HR Portal that I'm developing (ASP.NET MVC), and while I've managed to get it all set up to query the SQL Server database I've created, it currently works using a LIKE query, e.g.:
public List<Detail> Search(List<string> Information)
{
StringBuilder Buildsql = new StringBuilder();
Buildsql.Append("select * from UH_QA.dbo.Answers where ");
foreach (string value in Information)
{
Buildsql.AppendFormat("(Question like '%{0}%') and ", value);
}
string datasql = Buildsql.ToString(0, Buildsql.Length - 5);
return QueryList(datasql);
}
But in order to make sure the search function is fool proof, I want to use a query like this:
SELECT *
FROM UH_QA.dbo.Answers
WHERE CONTAINS(Question, '"Where" OR "do" OR "I" OR "put" OR "my" OR "phone"')
Any advice on how I might be able to go about changing what I've already got to split the string input by the user and then insert the individual words into the query?
My thoughts where to use value.Split(' ') to split the string by whitespace, but I'm open to suggestions.
You would achieve it by:
Changing the signature of QueryList so it allows an variable number of parameters.
Changing your foreach block to both populate an list of parameters and build the SQL. Do note that this would get rid of the SQL injection vulnerabilities.
In your QueryList method add the parameters to the command.
public List<Detail> Search(List<string> Information)
{
StringBuilder Buildsql = new StringBuilder();
Buildsql.Append("select * from UH_QA.dbo.Answers where ");
List<SqlParameter> queryParameters = new List<SqlParameter>();
for (int i = 0; i < Information.Count; i++)
{
if (!string.IsNullOrEmpty(Information[i]))
{
queryParameters.Add(new SqlParameter("#p" + i.ToString(), SqlDbType.VarChar) {
Value = Information[i]
});
if (i > 0)
{
Buildsql.Append(" OR ");
}
Buildsql.AppendFormat("Question like '%' + #p{0} + '%'", i);
}
}
return QueryList(datasql, queryParameters);
}
public List<Detail> QueryList(string query, IEnumerable<SqlParameter> parameters) {
// Do use the `parameters` when accessing the database
}

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;
}

Using dynamic type in LINQ queries

I'm using LINQ for querying the database. I'm using dynamic keyword in queries. I don't know this dynamic mechanism in depth, so I don't understand what's going on.
The situation follows. The following section of code:
var qGroup = qLocalOrd.GroupBy("new(...)", "it");
var qGroupCast = (qGroup as IQueryable<IGrouping<dynamic,dynamic>>).AsEnumerable();
var qAgg = from ordg in qGroupCast
select new {
ordg.Key,
Agg = (ordg.Key.OsID + " " + ordg.Key.NameOs + "\n" +
(ordg as IEnumerable<dynamic>).Aggregate("Составные части:\n", ...).Trim('\n') + ...)
};
Works just fine. But when I'm adding this to the end:
var qPlain = qAgg.Cast<dynamic>().AsQueryable().Select("new(Key.SubSchet, Key.NameSubSchet, ...)");
qPlain.Dump();
I'm receiving an error like "No field "Key" exists in type "Object"". It's the same if I use
(qAgg as IEnumerable<dynamic>)
So at this point dynamic treatment of qAgg elements is broken somewhy.
Why does this happen and how to make this thing work?

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