Convert string to int in linq query - linq

Here is the query
db.setupBrands.Where(x =>
Convert.ToInt32(x.SortKey) <= id &&
Convert.ToInt32(x.SortKey) >= desID)
.Select(x => x);
Here SortKey is string type i want to convert to int. On Convert.ToInt32() i got the following error.
LINQ to Entities does not recognize the method 'Int32 ToInt32(System.String)' method, and this method cannot be translated into a store expression.

EF can't translate Convert and Parse. I completely agree with the above, but, if your SortKey is nchar(4) you can try this:
string s_id = string.Format("{0:0000}", id);
string s_desID = string.Format("{0:0000}", desID );
db.setupBrands.Where(x =>
x.SortKey <= s_id &&
x.SortKey >= s_desID)
.Select(x => x);

Related

.net Core 3.1 Linq Expression "...could not be translated." Exception

var asd = (from a in _context.Nodes
where (Convert.ToDateTime(a.NodeProcessTime).Date >= DateTime.Now.Date.AddMonths(-5) && Convert.ToDateTime(a.NodeProcessTime).Date <= DateTime.Now.Date.AddMonths(-4))
select a).Count();
I am trying to get the count of the records between two dates. But an exception appears below. NodeProcessTime is a string. Needs to be converted to dateTime. Am I missing something?
System.InvalidOperationException: 'The LINQ expression 'Where(
source: DbSet,
predicate: (n) => ToDateTime(n.NodeProcessTime).Date >= DateTime.Now.Date.AddMonths(-5) && ToDateTime(n.NodeProcessTime).Date
<= DateTime.Now.Date.AddMonths(-4))' could not be translated. Either
rewrite the query in a form that can be translated, or switch to
client evaluation explicitly by inserting a call to either
AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync().
You could do something like this:
// Convert (I asumme) string to date
Date ToDate(string dateTime) => Convert.ToDateTime(dateTime).Date;
// Offset current datetime
Date OffsetNow(int offset) => DateTime.Now.Date.AddMonths(offset);
// Check date is between range
bool IsBetween(Date d) => ToDate(d) >= OffsetNow(-5) && ToDate(d) <= OffsetNow(-4);
var asd = _context.Nodes.Count(n => IsBetween(n));
you should use sqlFunction to translate it.
SqlFunctions.DateAdd("day", 0 , a.NodeProcessTime)
just add zero day to your string column
List<DateTime> dateTimes = new List<DateTime>();
foreach (var item in _context.Nodes.ToList())
{
dateTimes.Add(Convert.ToDateTime(item.NodeScanDateTime.Substring(0, 10)));
};
int counts = dateTimes.Where(a => a > DateTime.Now.AddMonths(-5)& a < DateTime.Now.AddMonths(-4)).Count();
Now at first I get the string NodeScanDateTime for all nodes and put them to a list. After that I cut them like "10.05.2020" type by using substring and convert them to DateTime. Then I made my query and now it works. Thanks for all...

linq Command not getting the answer for DB

i have a table(UserQuestions) in my DB(WebSiteUsers) which contains QuestionID field as a Primary key and QuestionContext field which holds the Questions that are asked as its value.
Now i want to have a textBox that show me the QuestionContext Value by getting QuestionID.
I used these linq commands and none of them bring me the correct answer :
string Questioncontext = new WebSiteUsersEntities().UserQuestions.Where(p => p.QuestiuonID.ToString() == QuestionID).Select(p => new { p.QuestionContext}).ToString();
string Questionx = (from q in new WebSiteUsersEntities().UserQuestions where q.QuestiuonID.ToString() == QuestionID select q.QuestionContext).ToString();
QuestionCntxt.Text = Questionx;
the outcome is like this :
SELECT
[Extent1].[QuestionContext] AS [QuestionContext]
FROM [dbo].[UserQuestion] AS [Extent1]
WHERE CAST( [Extent1].[QuestiuonID] AS nvarchar(max)) = #p__linq__0
I guess your QuestionID variable is of type string, while the database column is of type int.
So rather than using
q.QuestiuonID.ToString() == QuestionID
criteria inside the query, convert the variable to int and use that as criteria.
Also ToString just gives you the SQL query text, not the result. Use ToList if you expect more than one result or FirstOrDefault if you expect zero or one results:
var questionID = int.Parse(QuestionID);
string Questioncontext = new WebSiteUsersEntities().UserQuestions
.Where(p => p.QuestiuonID == questionID)
.Select(p => p.QuestionContext)
.FirstOrDefault();
Note that I also changed the select to return directly QuestionContext string rather than anonymous object having QuestionContext property.

try parse in linq

Hi I have a linq query as below
var perChange = (from data in globalDS.Tables[0].AsEnumerable().AsParallel()
select data.Field<double>("PercentChange")).ToList();
Now the dataset globalDS contains null as well as varchar values in them. So there is an obvious type cast error that is generated. Is there a way to try.Parse the value in "Percentage Change" column and select only the valid fields.
DataRow.Field supports nullable types:
List<double> result = globalDS.Tables[0].AsEnumerable().AsParallel()
.Where(r => r.Field<double?>("PercentChange").HasValue)
.Select(r => r.Field<double?>("PercentChange").Value)
.ToList();
Edit: Since you have mentioned that the field contains strings instead of doubles:
List<double> result = globalDS.Tables[0].AsEnumerable().AsParallel()
.Select(r => r.Field<string>("PercentChange").TryGetDouble())
.Where(nullDouble => nullDouble.HasValue)
.Select(nullDouble => nullDouble.Value)
.ToList();
I've used this extension to try-parse a string to double? which is safer than parsing "on the fly" into the local variable, especially with AsParallel:
public static Double? TryGetDouble(this string item, IFormatProvider formatProvider = null)
{
if (formatProvider == null) formatProvider = NumberFormatInfo.CurrentInfo;
Double d = 0d;
bool success = Double.TryParse(item, NumberStyles.Any, formatProvider, out d);
if (success)
return d;
else
return null;
}
How about this:
double temp;
var perChange = (
from data in globalDS.Tables[0].AsEnumerable().AsParallel()
where !data.IsNull("PercentChange")
&& double.TryParse(data.Field<string>("PercentChange"), out temp)
select double.Parse(data.Field<string>("PercentChange"))
).ToList();
Try a select using a where clause in which you check the type. This would be something like: where x != null && TypeOf(x) == double

LINQ to Entities does not recognize the method 'Char get_Chars(Int32)' method, and this method cannot be translated into a store expression

I would like to select only the records that have the field "1" from the string eventTriggers (that looks something like this : "00100010" )
I've tried and succesfully done so with more than 1 calls .. but i doubt its efficient. Basically I would want something like this ... but apprently LINQ does not support this.
(LINQ to Entities does not recognize the method 'Char get_Chars(Int32)' method, and this method cannot be translated into a store expression.)
using (var service = new dB.Business.Service.BaseBusinessService<memo>())
{
List<memo> result = service.Repository.GetQuery().Where(p => p.ID == ID && p.eventTriggers[index] == '1').ToList();
}
Any hints towards the correct solution ? Thank you !
I Had the same problem and solved It with substring.
ervice.Repository.GetQuery().Where(p => p.ID == ID && p.eventTriggers.Substring(index,1) == "1").ToList();
EF can't convert the char array operation into a valid query. How about
IEnumerable<Memo> memos
using (var service = new dB.Business.Service.BaseBusinessService<Memo>())
{
memos = service.Repository.GetQuery()
.Where(p => p.ID == ID).AsEnumerable();
}
var result = memos.Where(m => m.eventTriggers[index] == '1').ToList();
This gets all the memos with a matching ID locally then filters on the eventTriggers array.
Alternatively you could convert eventTriggers into a numeric value and use a bit mask, this would probably be a much faster query.
Linq looking like this,
using (var service = new dB.Business.Service.BaseBusinessService<Memo>())
{
result = service.Repository.GetQuery()
.Where(p =>
p.ID == ID
&&
m.eventTriggers & mask != 0).ToList();
}
more exapmles here
Solved:
using (var service = new dB.Business.Service.BaseBusinessService<memo>())
{
List<memo> result = service.Repository.GetQuery().Where(p => p.ID == ID && p.eventTriggers.Contains('1')).ToList();
}

LINQ read Select values

I have a LINQ query where I want to select and read the p.Api value.
var api = DataAccessNew.Instance.dcServers.Where(p => p.Ip == IpAddress).Select(p => p.Api);
How do I read the p.Api value?
I have tried api.ToString() but I get SQL instead of actual column value.
You are getting an IEnumerable<> back (and your ToString call is showing you the value of that expression).
If you are expecting a single value, do this:
var api = DataAccessNew.Instance.dcServers
.Where(p => p.Ip == IpAddress)
.Select(p => p.Api)
.Single();
You might be interested to read about the other methods like Single(): SingleOrDefault, First, FirstOrDefault. Which one you used depends on whether you are expecting a single or multiple values returned (Single vs. First) and what you want to happen if there are no values (the *Default methods will return the type default instead of throwing an exception).
Or if you want to look at all the returned values:
var api = DataAccessNew.Instance.dcServers
.Where(p => p.Ip == IpAddress)
.Select(p => p.Api);
foreach (var apiValue in api)
{
// apiValue will have the value you're looking for.
}
Try this snippet of code:
string apiValue = api.FirstOrDefault().ToString();
your syntex seems ok..
By the way try this
string api =DataAccessNew.Instance.dcServers.Where(p => p.Ip == IpAddress).Select(p => p.Api).FirstOrDefault();
if p.Ip is a unique key in your table you could try to add .FirstOrDefault() after your Linq query.
public string getselectedvalue(ListBox l)
{
string vtext="",vval="";
var selectedQueryText = l.Items.Cast<ListItem>().Where(item => item.Selected);
var selectedQueryVal = l.Items.Cast<ListItem>().Where(item => item.Selected).Select(item => item.Value);
vtext= String.Join("','", selectedQueryText ).TrimEnd();
vval= String.Join("','", selectedQueryVal ).TrimEnd();
return v;
}

Resources