LINQ decimal value in query - c#

I use:
Asp.net core
MongoDB Driver 2.4.2
I'm building a Mongo DB Linq query like hereunder:
This returns records as expected:
int.TryParse("1", out intVal);
query = query.Where(x => x.MyIntField == intVal);
This doesn't return any records while there are records that have MyDecimalField equal to 1.0:
decimal.TryParse("1.0", out decVal);
query = query.Where(x => x.MyDecimalField == decVal);
Does anybody have a clue why?

There can be two problems
First problem can be in your culture. Decimal separator in your culture is not . (maybe it is ,).
You can use decimal separator which your culture uses.
var parsed = decimal.TryParse("1,0", out decVal); // instead of "," use your culture decimal separator
if (parsed)
{
query = query.Where(x => x.MyDecimalField == decVal);
}
Or try to use InvariantCulture:
var parsed = decimal.TryParse("1.0", NumberStyles.Any, CultureInfo.InvariantCulture, out decVal);
if (parsed)
{
query = query.Where(x => x.MyDecimalField == decVal);
}
The second problem can be in parsing some text that cannot be parsed to decimal. If this text cannot be parsed then default value of decVal is 0 and filter by Where doesn't return values with MyDecimalField == 0.
You need to check if value is parsed and if it is then you can query some data.

Related

ASP.NET MVC Filtering results by date returns 0 results

I am trying to filter the results of a database query by date. The user will input a date value as a string and then I use that string to compare to the date of every query result to try to find a match, however there is never a match, even when I know one exists.
Query and filtering:
var documents = from s in db.Documents
select s;
if (!String.IsNullOrEmpty(searchString))
{
documents = documents.Where(s => s.Order_Date.ToString().Contains(searchString) ||
s.Comment.Contains(searchString));
}
It should be noted that if the searchString is found in the Comment column, then it works fine. But again, there is never a match for date.
In the SQL table that the app connects to the column Order_Date is of date datatype (not datetime). However in the model Order_Date is a DateTime variable because as far as I'm aware C# does not have just date.
Here is an example of the problem:
Result
What am I doing wrong?
You are comparing 11/8/2004 with s.Order_Date.ToString(). This approach has several problems:
Maybe s.Order_Date contains 2004-08-11 but when you do s.Order_Date.ToString() it turns to month-day-year date format 8/11/2004 (instead day-month-year) and 8/11/2004 != 11/8/2004
What happens if user enters 11/08/2004 ? 11/08/2004 != 11/8/2004. User will don't understand why they are no results.
If you want to search by date the best solution is to use a date entry control. If for your UX is important to enter date in a text control instead a date control then you should to tokenize text and try to identify dates on text, convert to date and use a date to compare on linq expression.
DateTime? search_date_start = tokenize_and_extract_date_start(searchString)
DateTime? search_date_end = tokenize_and_extract_date_end(searchString)
String? search_comment = remove_dates_from_search_string(searchString)
documents =
documents
.Where(s =>
search_date_start == null ||
s.Order_Date >= search_date_start)
)
.Where(s =>
search_date_end == null ||
s.Order_Date <= search_date_end)
)
.Where(s =>
search_comment == null ||
s.Comment.Contains(search_comment)
);
I figured it out using Jonathan's comment. This is the simplest way to do it:
if (!String.IsNullOrEmpty(searchString))
{
try
{
var test = DateTime.Parse(searchString);
documents = documents.Where(s => s.Order_Date == test);
}
catch (FormatException e)
{
documents = documents.Where(s => s.Comment.Contains(searchString));
}
}

C# LINQ Datetime in a String Value

I have a database with a string column that indicates a datetime value with this format: yyyyMMdd.
For example the value 20160908 indicate the 08 of Semptember 2016.
I have two datetimepicker for filter dateFrom and dateTo value. I take the datetime value in my datepicker textbox with this simply code:
DateTime dataFromSel = Convert.ToDateTime(txtDatFrom.Text);
DateTime dataToSel = Convert.ToDateTime(txtDatTo.Text);
My query is:
var query = from c in snd.WineOWines.OrderByDescending(x => x.DDT_DATA)
select new
{
c.ID,
c.VABRMA,
c.VABNCL,
c.DDT_DATA,
};
If I have a datetime filter i add this code:
if (txtDatDa.Text != "")
{
string dataDaSel = Convert.ToDateTime(txtDatDa.Text).ToString("yyyyMMdd");
int dataDa = Convert.ToInt32(dataDaSel);
query = query.Where(x => int.Parse(x.DDT_DATA) >= dataDa);
}
The problem is that i can't to list the query before the filter because i have a lot of rows and if i use this query i can't do an int.parse in the LINQ statement.
How can i write a LINQ statement that select the row in my DB with datetime between from and to, if the value in the column is a string?For now my query works fine, but i need a where clause for this problem.
Thanks to all
If dates have the same format you do not need to cast them to int.
You should be able to compare stings and remove the cast...
if (!string.IsNullOrEmpty(txtDatDa.Text))
{
string dataDaSel = Convert.ToDateTime(txtDatDa.Text).ToString("yyyyMMdd");
var res = query.Where(x => string.Compare(dataDaSel, x.Name) <= 0);
}
Linq to SQL supports string.Compare(string, string) as described here
https://social.msdn.microsoft.com/Forums/en-US/98180ae0-4ccd-4ecd-89d5-576a04169219/linq-to-entities-with-string-comparison?forum=adodotnetentityframework
You don't have to put int.Parse, you can do a direct string comparison it is going to work ok. Neither you have to convert your dataDaSel into integer.
if (txtDatDa.Text != "")
{
string dataDaSel = Convert.ToDateTime(txtDatDa.Text).ToString("yyyyMMdd");
query = query.Where(x => x.DDT_DATA >= dataDaSel);
}
E.g.
"20120201" >= "20120201" // true
"20120101" >= "20120201" // false
"20120301" >= "20120201" // true
As long as you keep format as yyyyMMdd it is going to work ok even with string.

using dt.AsEnumerable().Sum for columns having string/null value

I an using following way to get total of a column from a datatable
string total = dt.AsEnumerable().Sum(x => x.Field<decimal>("col1")).ToString();
This works fine when all the values of col1 are number.
My question is- lets consider if any one value of col1 is string or null or anything else other than number, the above code will throw error obviously.
Is there any way to check whether the value is number and use '0' instead if value is not number.
I tried -
string total = dt.AsEnumerable().Sum(x => x.Field<decimal>("col1") is int ? x.Field<decimal>("col1") : 0).ToString();
but not sure if it the correct way.
Please help
If it's not a decimal but a string you would even get a InvalidCastException in the Field<T> method. So you have to know what type it is.
I assume that Col1 can be null, Field<T> supports nullable types:
decimal total = dt.AsEnumerable()
.Sum(r => r.Field<decimal?>("Col1") ?? 0);
or without replacing null with 0:
decimal? total = dt.AsEnumerable()
.Sum(r => r.Field<decimal?>("Col1")); // use total.HasValue and total.Value
Presuming string, you could use decimal.TryParse:
decimal d = 0;
decimal total = dt.AsEnumerable()
.Where(r => decimal.TryParse(r.Field<string>("Col1"), out d))
.Sum(r => d);
If you don't know what type it is you could use object.ToString:
decimal total = dt.AsEnumerable()
.Where(r => !r.IsNull("Col1") && decimal.TryParse(r["Col1"].ToString(), out d))
.Sum(r => d);
Apart from that, why do you store the converted number again in a string variable?

How to query datetime literals and null values in Linq predicate?

In my current query I'm having an error like this:
The datetime literal value '2012-05-24' is not valid.
For regular linq query it seems like this:
_listHistory = (from item in dbase.histories
where item.UserID == details.UserID && item.FriendID.HasValue == true && item.LogDate < today
select item).OrderByDescending(x => x.LogDate).Take(take).Skip(skip).ToList();
I will be dealing with number of table "Columns" so I have to use linq predicate:
string predicate = string.Format("it.UserID=={0} && CAST(it.{1} as Edm.Int64) != null && it.LogDate <= DATETIME'{2}'",
details.UserID, columnname, string.Format("{0:yyyy-MM-dd}", today));
_listHistory = dbase.histories.Where(predicate)
.OrderByDescending(x => x.LogDate).Take(take).Skip(skip).ToList();
But this query result the error above. Can anyone help me to construct my linq query?
It is my first time to deal with Linq predicates and literals.
You could likely use the dynamic LINQ support instead, but assuming this is Entity Query Language, it appears that you can construct the datetime with a call to CreateDateTime:
http://msdn.microsoft.com/en-us/library/bb738563.aspx
CreateDateTime( year, month, day, hour, minute, second)

LINQ OR operator not giving result

I have written a LINQ query with or condition in it, but its not working, it seem I am doing something wrong.
I am passing a string value and on it, I want to get my result.
var userDetails = context.tbl_members.Where
(
d => d.Mobile == value
||
d.MemberId == Int32.Parse(value)
).SingleOrDefault();
its not working if someone put a mobile no, but if work with memberID
if I split the query keep only mobile no its running fine.
var userDetails = context.tbl_members.Where(d => d.Mobile == value ).SingleOrDefault();
Please check what I did wrong with or condition
Regards
Moksha
var userDetails = context.tbl_members
.Where(d => d.Mobile == value ||
d.MemberId == Int32.Parse(value))
.SingleOrDefault();
It looks like you are using Linq to Entities or Linq to Sql. Int32.Parse() is not supported in that context - just do the number conversion before your query:
int numValue = Int32.Parse(value);
var userDetails = context.tbl_members
.Where(d => d.Mobile == value || d.MemberId == numValue)
.SingleOrDefault();
thanks for your help brokenGlass,
the error was in converting from string to int, as I was passing string of 10 digits, it was not getting converted into int
Value was either too large or too small for an Int32.
thanks

Categories

Resources