C#: SQL Query Builder Class - c#

Where can I find a good SQL Query builder class. I just need a simple class to build a SQL string and that is it. I will need it for C# and MySql. I really don't need anything like Linq or NHibernate. Thanks

Since Google leads me to this page,
I would suggest SqlKata, a simple but powerful SqlQuery Builder, that supports nested where conditions, subqueries and joins.
Currently it supports SqlServer, MySql and PostgreSql
var query = new Query("Users")
.LeftJoin("Countries", "Users.CountryId", "Countries.Id")
.Where("Status", "blocked")
.OrWhereIn("Id", new [] {10, 11, 12})
.OrWhere("LastLogin", ">", DateTime.UtcNow.AddMonths(-5));
Note: I am the owner of it
Difference between different compilers output
MySql: https://sqlkata.com/playground/mysql?code=var%20query%20=%20new%20Query(%22Posts%22).Limit(10).Offset(20)%3B
SqlServer: https://sqlkata.com/playground/sqlserver?code=var%20query%20=%20new%20Query(%22Posts%22).Limit(10).Offset(20)%3B
Oracle: https://sqlkata.com/playground/oracle?code=var%20query%20=%20new%20Query(%22Posts%22).Limit(10).Offset(20)%3B

I use this code..It Escapes the strings too i hope it Helps:
class Mysql
{
public static string INSERT(string INTO, NameValueCollection VALUES)
{
string queryString = "INSERT INTO " + INTO + " (";
for (int i = 0; i < VALUES.Count; i++)
{
queryString += VALUES.Keys[i] + (i + 1 == VALUES.Count ? "" : ",");
}
queryString += ") VALUES (";
for (int i = 0; i < VALUES.Count; i++)
{
queryString += Escape(VALUES[VALUES.Keys[i]]) + (i + 1 == VALUES.Count ? ("") : (","));
}
queryString += ");";
return queryString;
}
public static string DELETE(string FROM, NameValueCollection WHERE)
{
string queryString = "DELETE FROM " + FROM + " WHERE";
for (int i = 0; i < WHERE.Count; i++)
{
queryString += " " + WHERE.Keys[i] + "=" + Escape(WHERE[WHERE.Keys[i]]);
}
queryString += ";";
return queryString;
}
public static string UPDATE(string UPDATE, NameValueCollection SET, NameValueCollection WHERE)
{
string queryString = "UPDATE " + UPDATE + " SET";
for (int i = 0; i < SET.Count; i++)
{
queryString += " " + SET.Keys[i] + "=" + data.Escape(SET[SET.Keys[i]]) + (i + 1 == SET.Count ? ("") : (","));
}
queryString += " WHERE";
for (int i = 0; i < WHERE.Count; i++)
{
queryString += " " + WHERE.Keys[i] + "=" + data.Escape(WHERE[WHERE.Keys[i]]);
}
queryString += ";";
return queryString;
}
public static string SELECT(string[] SELECT, string FROM, NameValueCollection WHERE)
{
string queryString = "SELECT ";
for (int i = 0; i < SELECT.Length; i++)
{
queryString += SELECT[i] + (i + 1 == SELECT.Length ? ("") : (","));
}
queryString += " FROM " + FROM + " WHERE ";
for (int i = 0; i < WHERE.Count; i++)
{
queryString += " " + WHERE.Keys[i] + "=" + Escape(WHERE[WHERE.Keys[i]]);
}
queryString += ";";
return queryString;
}
public static string Escape(string input)
{
using (var writer = new StringWriter())
{
using (var provider = CodeDomProvider.CreateProvider("CSharp"))
{
provider.GenerateCodeFromExpression(new CodePrimitiveExpression(input), writer, null);
return writer.ToString();
}
}
}
}
You use it like this:
NameValueCollection nvc_for_SET_and_VALUES=new NameValueCollection();
NameValueCollection nvc_for_WHERE= new NameValueCollection();
nvc_for_WHERE.Add("arg1","value1");
nvc_for_WHERE.Add("AND arg2","value2");
nvc_for_WHERE.Add("OR arg2","value3");
nvc_for_SET_and_VALUES.Add("arg", "value");
nvc_for_SET_and_VALUES.Add("arg2", "value2");
string[] fieldsToSelect= { "arg1", "arg2" };
Mysql.DELETE("mytable", nvc_for_WHERE);
Mysql.INSERT("mytable", nvc_for_SET_and_VALUES);
Mysql.SELECT(fieldsToSelect, "mytable", nvc_for_WHERE);
Mysql.UPDATE("mytable", nvc_for_SET_and_VALUES, nvc_for_WHERE);

You could probably use the framework class CommandBuilder. Check out:
http://msdn.microsoft.com/en-us/library/tf579hcz.aspx

If you are using .NET 4 and don't mind using dynamics you can use Massive, created by Rob Conery, this single file Database requires no dlls, just drop the Massive.cs file and you ready to go.
You can use the Massive to build queries like this.
//grab all the products
var products = table.All();
//Or
var productsFour = table.All(columns: "ProductName as Name", where: "WHERE categoryID=#0",args: 4);
You can also run ad-hoc queries as needed:
var result = tbl.Query("SELECT * FROM Categories");

Mohammed Hadi, with DbExtensions your sample can be like this:
public static string InsertQuery(string into, NameValueCollection values)
{
var query = SQL
.INSERT_INTO(into + " (" +
String.Join(" ,", values.Keys.Cast<String>().ToArray()) +
")")
.VALUES(values.Keys.Cast<String>().Select(key => values[key]));
return query.ToString();
}

Related

Keep int variables values from dataReader c#

I don't have much experience with C# but I am trying to make a simple windows forms app with personal finances.
So, I have 2 dataReader (I am using the Oracle provider), and the sql (oracle table) commands that select only 2 columns from a table, only with 1 value, mainly income 1 and income2 and the sum of all values from a specific month.
the sql strings look like this:
strSQL_sel_income1 = "select DISTINCT categorie,SUM(suma) from financiar where main_categ='income' and categorie IN ('income1') and EXTRACT(month FROM data)=" + luna_income + " Group by categorie";
strSQL_sel_income2 = "select DISTINCT categorie,SUM(suma) from financiar where main_categ='income' and categorie IN ('Income2') and EXTRACT(month FROM data)=" + luna_income + " Group by categorie";
the "luna_income" value is taken from a combobox where I select a specific month.
The problem is when I try to declare an Int variable from the values I get with data reader and these variables are not kept outside the while statement... dr_income1/2 being the dataReader
if (dr_income1.HasRows)
{
while (dr_income1.Read())
{
label26.Text = dr_income1.GetString(0) + ": " + dr_income1.GetInt32(1) + "\n";
int suma_income1 = dr_incomei1.GetInt32(1);
}
}
else
{
label26.Text = "No info;
}
so, I have two similar data readers and two int variables suma_income1 and suma_income2. If I try to make a sum of them, outside the WhIle codes, I get a zero value. Where should I declare the two variables and how to keep their values?
int suma_income_total = suma_income1 + suma_income2;
label29.Text = "Income total: " + suma_income_total;
The suma_income_total is ZERO!!!
dr_income1 = cm1.ExecuteReader();
dr_income2 = cm2.ExecuteReader();
label26.Text = "";
label28.Text = "";
if (dr_income1.HasRows)
{
while (dr_income1.Read())
{
label26.Text = dr_income1.GetString(0) + ": " + dr_income1.GetInt32(1) + "\n";
int suma_income1 = dr_income1.GetInt32(1);
}
}
else
{
label26.Text = "No info";
}
if (dr_income2.HasRows)
{
while (dr_income2.Read())
{
label28.Text = dr_income2.GetString(0) + ": " + dr_income2.GetInt32(1) + "\n";
int suma_income2 = dr_income2.GetInt32(1);
}
}
else
{
label28.Text = "no info";
}
int suma_income_total = suma_income1 + suma_income2;
label29.Text = "income total: " + suma_income_total;
dr_income2.Close();
dr_income1.Close();
I put some changes in your code. It is not ideal since there are several much simple ways. But it is ok as workaround:
dr_income1 = cm1.ExecuteReader();
dr_income2 = cm2.ExecuteReader();
label26.Text = "";
label28.Text = "";
var suma_income1 =0;
var suma_income2 =0;
if (dr_income1.HasRows)
{
while (dr_income1.Read())
{
label26.Text = dr_income1.GetString(0) + ": " + dr_income1.GetInt32(1) + "\n";
suma_income1 += dr_income1.GetInt32(1);
}
}
else
{
label26.Text = "No info";
}
if (dr_income2.HasRows)
{
while (dr_income2.Read())
{
label28.Text = dr_income2.GetString(0) + ": " + dr_income2.GetInt32(1) + "\n";
suma_income2 += dr_income2.GetInt32(1);
}
}
else
{
label28.Text = "no info";
}
int suma_income_total = suma_income1 + suma_income2;
label29.Text = "income total: " + suma_income_total;
dr_income2.Close();
dr_income1.Close();

Need Help the best overloaded method match for 'string.endswith(string)' has some invalid arguments

dynamic counter = 1;
string FileNameWithoutExtestion = "";
FileNameWithoutExtestion = file.Split('.')[0];
string FileExtestion = file.Split('.')[1];
while (System.IO.File.Exists(Dir + file))
{
if (true)
{
counter = counter + 1;
if (FileNameWithoutExtestion.EndsWith('_'))
{
file = FileNameWithoutExtestion + counter.ToString() + "." + FileExtestion;
}
else
{
file = FileNameWithoutExtestion + "_" + counter.ToString() + "." + FileExtestion;
}
}
}
if (FileNameWithoutExtestion.EndsWith('_')) //the error occurred here
Whats wrong ?
String.EndsWith() only has overloads with string as parameter, you insert a char.
Replace
.EndsWith('_')
with
.EndsWith("_")
and i would use those path-methods to parse filenames and extensions
string FileNameWithoutExtestion = System.IO.Path.GetFileNameWithoutExtension(file);
string FileExtestion = System.IO.Path.GetExtension(file); //.jpg
because FileNameWithoutExtestion = file.Split('.')[0]; will lead to a invalid value in case of a filename like foo.bar.jpg

put data from simpleDB into data gridview

I was trying to retrieve data from Amazon SimpleDB and currently it only displays data in text like domainName: {attribute1, value2} {attribute1, value2}.
How can I show the data in data grid view? My code is as follows:
public static List<String> GetItemByQuery(IAmazonSimpleDB simpleDBClient, string domainName)
{
List<String> Results = new List<String>(); ;
SelectResponse response = simpleDBClient.Select(new SelectRequest()
{
SelectExpression = "Select * from " + domainName
});
String res = domainName + " has: ";
foreach (Item item in response.Items)
{
res = item.Name + ": ";
foreach (Amazon.SimpleDB.Model.Attribute attribute in item.Attributes)
{
res += "{" + attribute.Name + ", " + attribute.Value + "}, ";
}
res = res.Remove(res.Length - 2);
Results.Add(res);
}
return Results;
}
How you an read here:
http://docs.aws.amazon.com/sdkfornet1/latest/apidocs/html/P_Amazon_SimpleDB_Model_SelectResult_Item.htm
your response.Items is
public List<Item> Item { get; set; }
so you should directly use to DataSource of your Grid, set autogenerate column to your grid to start to view the result

NameValueCollection from Form.Post show FIELDS and VALUES

I need to grab all the FIELD and VALUES from a POST.
I have the follow which only return the FIELDs but no Values.
NameValueCollection authForm = Request.Form;
String[] a = authForm.AllKeys;
for (i = 0; i < a.Length; i++)
{
frm += ("Form: " + a[i] + " : " + "<br>");
}
Response.Write(frm);
What can I add this the frm string to show the VALUES ?
UPDATE:
I used the initial code of
NameValueCollection authForm = Request.Form;
foreach (string key in authForm.AllKeys)
{
frm += ("Key: " + key + ", Value: " + authForm[key] + "<br/>");
}
which worked great. I will try the new variation below.
NameValueCollection authForm = Request.Form;
StringBuilder sb = new StringBuilder();
foreach (string key in authForm.AllKeys)
{
sb.AppendFormat(
"Key: {0}, Value: {1}<br/>",
HttpUtility.HtmlEncode(key),
HttpUtility.HtmlEncode(authForm[key])
);
}
Response.Write(sb.ToString());

Build comma seperated string from the struct in C#

I have the following struct in C# class
public struct Employee
{
public const string EMPID = "EMP_ID";
public const string FName = "FIRST_NAME";
public const string LNAME = "LAST_NAME";
public const string DEPTID = "DEPT_ID";
}
Is there an easy way to build a string as follows
const string mainquery="INSERT INTO EMP(EMP_ID,FIRST_NAME,LAST_NAME,DEPT_ID) VALUES(:EMP_ID,:FIRST_NAME,:LAST_NAME,:DEPT_ID)"
Instead of doing as follows
and then concatenating it.
const string EMP_COLS=
EMPLOYEE.EMPID + "," +
EMPLOYEE.FNAME + "," +
EMPLOYEE.LNAME + "," +
EMPLOYEE.DEPTID;
const string EMP_Values=
EMPLOYEE.EMPID + ":" +
EMPLOYEE.FNAME + ":" +
EMPLOYEE.LNAME + ":" +
EMPLOYEE.DEPTID;
You could try something like this:
StringBuilder sb = new StringBuilder();
var fields = typeof(Employee).GetFields();
for (int i = 0; i < fields.Length; ++i)
{
sb.Append(fields[i].GetValue(new Employee()));
if (i < fields.Length - 1)
{
sb.Append(',');
}
}
string result = sb.ToString();
// The above will be "EMP_ID,FIRST_NAME,LAST_NAME,DEPT_ID"
Edit: Note that above I'm assuming you've got using directives for both System.Reflection and System.Text.
If the struct held readonly properties rather than public consts you could do it with Reflection. You could call Type.GetProperties, loop through them all and call them to get out the values and insert the values into a List<string> and then join them with string.Join(", ", myList); or something.
You'd then get the first part of the string as EMP_ID, FIRST_NAME, LAST_NAME, DEPT_ID and you'd need to make a copy of that and add the :s as needed and you'd have both parts.
you can use the string.Format(string format, object[] arg) Method as follows:
string query = string.Format("INSERT INTO EMP({0},{1},{2},{3}) VALUES(:{0},:{1},:{2},:{3})",
Employee.EMPID,
Employee.FNAME,
Employee.LNAME,
Employee.DEPTID);
Hope that helps.
You will need some kind of mapping dictionary, like here, or you could just use some ORM tool to do the mapping for you.
string[] values = new[] {
"EMP_ID",
"FIRST_NAME",
"LAST_NAME",
"DEPT_ID",
};
var columns = string.Join(",", values);
var parameters = ":" + string.Join(",:", values);
var sql = string.Format("INSERT INTO EMP({0}) VALUES({1})",
columns,
parameters);
string[] cols = typeof(Employee).GetFields()
.Select(f => f.GetValue(null).ToString()).ToArray();
Console.WriteLine(string.Format(
"INSERT INTO EMP({0}) VALUES(:{1})",
string.Join(",", cols),
string.Join(",:", cols)));

Categories