I want to filter dates range. I'm using the dynamic LINQ library. I have to build my where string into a variable based on several factors and then pass the string variable to the where clause.
In my ASP.NET MVC project I wrote a helper.
private string GetFilterCondition(string filterCondition, string filterDataField, string filterValue)
{
switch (filterCondition)
{
case "CONTAINS":
return " " + filterDataField + ".Contains(\"" + filterValue + "\")";
case "GREATER_THAN_OR_EQUAL":
return " " + filterDataField + " >= " +"\"" + filterValue + "\"";
case "LESS_THAN_OR_EQUAL":
return " " + filterDataField + " <= " + "\"" + filterValue + "\"";
}
return "";
}
And I used parameter in query which I've passed from the ASP.NET MVC project;
public int GetFilteredCount(string searchValue)
{
var filteredRecords = 0;
try
{
var query = DB.Categories.AsQueryable();
var totalRecords = query.Count();
if (!string.IsNullOrEmpty(searchValue))
{
searchValue = searchValue.Trim();
query = query.Where(searchValue);
}
filteredRecords = query.Count();
}
catch (Exception e){}
finally
{
DestroyDbContext();
}
return result;
}
When filtering date range ("GREATER_THAN_OR_EQUAL", "LESS_THAN_OR_EQUAL"), I get an error:
Operator '>=' incompatible with operand types 'DateTime' and 'String'
Please note, that with 'contains' works.
I uploaded picture to see what looks like searchvalue parameter
I rewrote GetFilterCondition function like this:
case "GREATER_THAN_OR_EQUAL":
return string.Format(" {0} >= DateTime.Parse(\"{1}\")", filterDataField, filterValue);
case "LESS_THAN_OR_EQUAL":
return string.Format(" {0} <= DateTime.Parse(\"{1}\")", filterDataField, filterValue);
after executed filteredRecords = query.Count() throws this error:
LINQ to Entities does not recognize the method 'System.DateTime Parse(System.String)' method, and this method cannot be translated into a store expression
Having this code:
var code = "public class TestClass {" +
" public int HelloWorld(int num) {" +
" return 5 + num;" +
" }" +
"}";
var script = CSharpScript.Create(code);
var x = (await script.RunAsync()).ReturnValue;
How does one pass a value for the parameter, call the method and read the return value?
Continue with another code is the simplest.
var call = await script.ContinueWith<int>("new TestClass().HelloWorld(3)").RunAsync();
var x = call.ReturnValue;
By the way, CSharpScript is a scripting engine which does not require you having class and method like ordinary C# program. You can just use 5 + num as script content.
var code = "5 + num";
var numValue = 3;
var setParam = await CSharpScript.RunAsync("var num = " + numValue + ";");
var runCode = await setParam.ContinueWithAsync(code);
var x = runCode.ReturnValue;
For full example, take a look of RoslynScript/Script.cs
I am trying to loop over an object properties and values and build a string with them.
The problem is i cant seem to access the values of the properties which are not string...
Here is what i have so far:
private string ObjectToStringArray(CustomType initParameters)
{
var stringArray = "";
foreach (var parameter in initParameters.GetType().GetProperties())
{
if (parameter.PropertyType.Name == "String")
stringArray += "\"" + parameter.Name + "\" => \"" + parameter.GetValue(initParameters) + "\",\r\n";
else
{
stringArray += "array(\r\n";
foreach (var subParameter in parameter.PropertyType.GetProperties())
{
stringArray += "\"" + subParameter.Name + "\" => \"" + subParameter.GetValue(parameter) + "\",\r\n";
}
stringArray += "),";
}
}
return stringArray;
}
i can get to the values of all the string properties but one level down i just cant extract the property object itself.
My exception is: System.Reflection.TargetException: Object does not match target type.
When calling subParameter.GetValue(parameter), you are passing a PropertyInfo, whereas you seemingly want to pass the value of that property for initParameters instead.
You should thus pass parameter.GetValue(initParameters) to subParameter.GetValue() instead.
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();
}
Edit:
DataClassesDataContext dc = new DataClassesDataContext();
string _idCompany = Request["idCompany"];
var newes = dc.GetNewsCompany(Int64.Parse(_idCompany));
string date = "";
string newsHtml = "<center>";
if(newes.GetEnumerator().MoveNext()){
foreach (var item in newes)//say Error .......................
{
// date = calendar.GetDayOfMonth(item.DateSend) + "/" + calendar.GetMonth(item.DateSend) + "/" + calendar.GetYear(item.DateSend).ToString();
// newsHtml += "<li class='news-item'><a style='text-decoration:none' class=\"link\" onclick=\"$(\'#BodyNews\').text(\'" + HttpUtility.HtmlEncode(item.Body).Trim() + "\');$(\'#BodyNews\').dialog({resizable:false});\" href=\"#\" > " + item.Title.ToString() + "</a> " + date + " </li>";
}
newsHtml += "</center>";
}
else
{
// var propertyCompany = dc.GetPropertyCompanyById(Int64.Parse(_idCompany));
// newsHtml += "<li class='news-item'><a style='text-decoration:none' class=\"link\" );$(\'#BodyNews\').dialog({resizable:false});\" href=\"#\" > " + "!به صفحه شخصی شرکت " + propertyCompany.FirstOrDefault().NameCompany + " خوش آمدید " + "</a> " + date + " </li>";
}
return newsHtml;
say error:The query results cannot be enumerated more than once
how check var is empty or null with out enumerated;
Why bother with the if at all?
var newes = dc.GetNewsCompany(Int64.Parse(_idCompany));
//if (newes.GetEnumerator().MoveNext())//check is null or empty
var newesList = newes.ToList();
if (neweList.Count > 0)
{
...
}
You can always check the newesList.Count property afterward.
Not sure what's available as a member in newes, but if it's an object and depending on what dc.GetNewsCompany returns you could check for null
if (news == null) return;
or if it returns an empty collection/array, just check the count/length:
if (news.Count == 0) return;
if (news.Length == 0) return;
the error comes, because you are using .GetEnumerator() on newes and then using the newes again in a foreach Loop .. this causes the "double enumeration".
Generally avoid walking "such var"'s with a foreach, since the DataReader is locked the whole loop !. Means that you cannot use the same entitie in this loop.
Better .ToList() , you can the list.AsQuearable agian if you want to Linq on it
f.e. something like
var newes = dc.CompanyTable.Where(ln => ln.id.Equals(_idCompany));;
List<CompanyTable> newesList = newes.ToList();