I have a column named Rule in DB for storing one line of c# code, I want to retrieve them to.net program. The problem is, the retrieved line by lambda expression is not recognizable by .net program because of the c# class name in it. So is that the dynamical linq limit which can't implement it or not?
Expample 1:
Retrieved string from DB:
Regex.IsMatch(string.Concat(fieldValue1.Where(q => !Path.GetInvalidFileNameChars().Contains(q))), #"\d{11}")
Lambda Expr consuming the above retrieved string:
var result = fieldInfo.Where(RetrievedstringfromDB, Value)
The error is
No property or field 'Regex' exists in type 'XXX'
The closest thing I found that would do that is using Roslyn to run the whole thing dynamically, but to be fair that might not a good workaround for the project I am working on now, any lights/thoughts would be much appreciated!
Related
I have records that have a string property called Project. The values these normally have are like A-A-40019-0 but in reality they could be anything.
I need to be able to extract the numeric values from the Project project property so that I can then try and cast it to a ulong so that it can be sorted by.
I'm trying the following code to select the number values from the Project property.
return jobs.Select(x => new JobViewModel
{
Sequence = x.Project.Where(y => char.IsDigit(y)).ToString()
});
When I try this I get the following error
DbExpressionBinding requires an input expression with a collection
ResultType.
I need to use Linq to Entities as I can't afford to load all records into memory.
I'm using SQL Server.
You don't say which DB you are using but I did find this for SQL Server. https://www.mytecbits.com/microsoft/sql-server/extract-numbers-from-string#:~:text=%20Extract%20Numbers%20From%20String%20In%20SQL%20Server,you%20want%20to%20split%20this%20delimited...%20More%20
Hopefully similar technique can be used for the DB you are using.
You could make a view with a column calling that function added on the end and then you can sort it.
or purely in C# which I haven't tried:
Convert.ToInt32(new string(y.project.Where(c => Char.IsDigit(c)).ToArray())
I save my data in a binary-look string, "100010" ,for example. And I want to check whether it has same value in corresponding place with the other string "100000".
So I try to use "Intersection". In this Condition, the result of intersection will be "100000", and it could be seen as the item I need for my requirement. But how can I use this conception when I query a Entity to Linq statement?
Here is my thought:
var chemicals = db.ChemicalItem.Where(c => c.CategoryNumber.ToCharArray().Intersect(catekey.ToCharArray()).Count()>0);
"CategoryNumber" is my data, and "catekey" is the string for comparing. Both of them are binary-look string(cantain 6 chars). And if the count is not 0,they have '1's in the same index. And I can get the correct query.
Sadly, It didn't work. I always get DbExpressionBinding Error. Can somone tell me What's Wrong? Thanks.
PS:I'm not good at English and post the question here first time, sorry for my bad expression and thank for your reading.
LINQ to Entities is trying to create a SQL query out of your condition, but is not able to do it for the expression you specified.
One way to "fix" the problem would be to do the filtering in code instead of in SQL, but this will impact performance, because all of the records will be retrieved to the client and filtered there. This is how you could do it (notice the added ToList()):
var chemicals = db.ChemicalItem.ToList().Where(c => c.CategoryNumber.ToCharArray().Intersect(catekey.ToCharArray()).Count()>0);
A suggested way would be to do the filtering in SQL, but in this case you will need to write an equivalent stored procedure in SQL which will do the filtering and call that from your EF code. Still such filtering will not be very effective because SQL will not be able to use any indices and will always need to do a table scan.
I having issues with SQL Azure, the following LINQ with EF code works fine if the database is SQL Server 2012
var userLength = users.Select(n => new { n.FirstName.Length });
But, if I point it to an Azure database and I get
"base = {"The cast to value type 'Int32' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type."}"
Any ideas?
Do the databases contain same data?
Maybe one of users has no FirstName set in Azure database?
I guess it's when you iterate over usersLength that you receive this Exception? Is it thrown on first iteration or maybe later?
Here's what I think is happenning (I'm using LINQ to Objects here)
You can edit it like this to make it return 0 for null elements (FirstNames):
You can download those two code snippets if you have LinqPad here (they will be automatically opened in LinqPad):
http://share.linqpad.net/2pfjqf.linq
http://share.linqpad.net/vp96kf.linq
I'm getting the error:
LINQ to Entities does not recognize the method 'Int32 LastIndexOf(System.String)'
method, and this method cannot be translated into a store expression.
When using this code to tell if a person's last name starts with certain characters:
persons = persons.Where(c => c.FullName.IndexOf(" ") > 0 &&
c.FullName.Substring(c.FullName.LastIndexOf(" ")+1).StartsWith(lastNameSearch));
Any clue how to achieve this without using LastIndexOf()? Maybe I have to check for this after I grab results from the database using ToList()?
You are limited by the set of canonical functions that can be translated into an SQL query, so any solution must be achieved with no more than the canonical functions offer.
Luckily, one of the supported functions is the bool Contains(string) instance method. You can rewrite your check as
persons = persons.Where(c => c.FullName.Contains(" " + lastNameSearch));
This is not exactly like your current version (because it will allow people with more than one name to match their second name, while the former won't), but it's pretty close and IMHO can be acceptable.
Of course it would be much better than any of this to keep the last names as a separate column in the database, if that is at all possible.
So, in my last post I was asking how to build a dynamic search filter using LINQ and EF4 (See Here) and finally came up with the solution of building the expression as a string and parse it to an expression using the Dynamic LINQ library.
I that solved the problem. I was able to generate a Expression<Func<TSource, out bool>> and pass it to the Where() method of the DbSet. I am also trying to do this using MySql as a database behind EF4.
The problem came when I tried to apply string operations to integers, like searching a database record which consecutive number starts with 1234.
My initial expression was something like: record.ConsecutiveNumber.ToString().StartsWith("1234"). Sadly, as expected, things were not that easy as EF4 fails to query the DbSet with exception:
"LINQ to Entities does not recognize
the method 'System.String ToString()'
method, and this method cannot be
translated into a store expression."
After some Google search I found that this is a common problem. But C'MON! Is there a way to perform a search function that can search records with a consecutive number starting by "1234"?
How pros implement search features with EF4? This is with a single property filter. What if I wanna add multiple filters? God, my head hurts... :/
Thanks!
EDIT:
Thought #1: What about a stored procedure? What about calling a MySql stored procedure from Linq? Am I aiming way too high?
You can use the SqlFunctions.StringConvert method. It requires a double (or decimal) so you'll have to cast your int ConsecutiveNumber.
Replace:
record.ConsecutiveNumber.ToString().StartsWith("1234")
With:
SqlFunctions.StringConvert((double)record.ConsecutiveNumber).StartsWith("1234")
Have you looked at the Dynamic LinQ Library:
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
And for your question
How to use "contains" or "like" in a dynamic linq query?
Previously I have gotten the code for this lib and just taken a look inside, it is pretty easy to follow.
This would be my thought process on getting it to work. Hopefully it points you in the right direction.
According to other posts SqlFunctions.StringConvert((double)record.ConsecutiveNumber) works for Sql Server.
Problem with converting int to string in Linq to entities
And here is relevant information on linq conversions.
Linq int to string
And here is an answer hinting at writing your own sql function for stringconvert
Using a SQL Function in Entity Framework Select
If SqlFunctions.StringConvert doesn't work for you I'd suggest looking at figuring out how to do it in Sql and then writing your own [EdmFunction()] attribute based method.
I haven't got a clue if this will work over Linq to EF or not but presuming that they mapped the Math operations, this might solve your need:
record.ConsecutiveNumber / Math.Pow(10, Math.Truncate(Math.Log10(record.ConsecutiveNumber) - 3)) == 1234
This is basically dividing the number by a power of 10 just big enough to leave the first 4 digits.
I know this is very hacky and inefficient even if it works, but there you go. :)
Any method calls in a LINQ to Entities query that are not explicitly mapped to a canonical function will result in a runtime NotSupportedException exception being thrown.
Check mapping canonical function here:
http://msdn.microsoft.com/en-us/library/bb738681.aspx
In this case, you can use Math function. (I don't think code first can use in product project at that time)