Regex in Linq (EntityFramework), String processing in database - c#

I have a column in my table which contains values as
"FilterA:123,234,34;FilterB:12,23;FilterC:;FilterD:45;"
Filters are separated by ';' and the values of each filter are separated by ','. There is a ':' in between a Filter's name and it's values.
Now, can I do anything which could fetch out the values part only? Like "123,234,34" for "FilterA". Or can I give it a number like "234" to search in the value part of "FilterA" and/or "54" in the value part of "FilterB"? I know it is possible with using regex, i guess, but I have no idea how.

You can't use regular expressions in Linq to Entities queries, because they cannot be translated into SQL. You even can't use String.Split to split your filters by ;. You have two options here:
Change database table structure. E.g. create table Foo_Filter which will link your entities to filters. And then create table Filters which will contain filters data.
Execute query in memory and use Linq to Objects. This option will be slow, because you have to fetch all data from database to memory

If your underlying database provider is SQL Server then you could make use of SqlMethods.Like to filter the database result set down to a manageable subset of data that can then be analysed locally with RegEx

+1 for #lazyberezovsky, you can't do regex in Linq to Entities because it can't translate that into SQL. You could pull all records back into memory then do Linq to Objects on it (do a .ToList() to a variable then a second linq query for this regex) but that means you'll load every db record into memory to process this query. Same recomendations: change the DB structure such that you don't need to do this.

I guess if you wanted everything to execute on the database server you'd need a SQL function that could parse these filters, perhaps returning a multi-column table. Unfortunately I am not on a machine where I could provide any sample code.

Related

Filter string match without regex

I want to filter a column with type string in a a collection result with Like here the logic :
so my logic I want to display all matches when the char before and after my search word in the sentence is in any of my delimiters, if not i don't display the row.
The thing you want is hard to impossible to do using like and string operations in database. And even when you get it right it will be slow. What you should do is use mysql feature full text search. And yes Entity Framework nor linq is supporting this syntax so you will have to circumvent the EF and write that query in a string.
_supplierDbContext.Database.SqlQuery<DTO>(
"select something from table match (column) against (:keywords)",
new SqlParameter(":keywords",keywords))

Entity Framework String Size Limitation on Contains Clause

So, I have this lambda expression and it works just fine
list = list.Where(x => x.ListaDocumentoCaixa.Any(d => d.Observacao.Contains(term.Trim())));
I must add that this column is a varchar(6000) field. So far, this has been working just fine as I mentioned, but just recently I've ran into an issue. It seems that if the term of the search occurs from position 4001 of the string and on, the query fails to return anything to me.
After some debbuging I've found this commented on the query produced by Entity Framework
-- p__linq__0: 'maria stela gonsa' (Type = String, Size = 4000)
Then after some research I found this to be Entity's common behaviour, however, I can't have this kind of limitation on the application. My question is: Is there any way to change this behaviour ? I would like very much to avoid having to write this query as plain text and run this with ExecuteQuery if possible.
Thanks in advance for the help!
I would recommend you follow the following article, assuming you are using SQL server, about how to create a full text search index, and use it in Entity Framework with C#.
Running LIKE statements (which is what Contains() maps to) is HIGHLY inefficient on large varchar fields.
https://www.mikesdotnetting.com/article/298/implementing-sql-server-full-text-search-in-an-asp-net-mvc-web-application-with-entity-framework
EDIT: The summary of the link is:
1.) Create a full text index on the field using SQL server's wizard. That full text field will allow CONTAINS and FREETEXT searches on the whole field, and be much more efficient.
2.) Write a stored procedure that joins the table in question to results from the free text index.
3.) Make an Entity Framework class to represent results from that stored procedure, and use EF to call in and return a list of those results.

parse all value of a column

I have a data table
and it contains some int type columns, some type double columns, some date type columns
what i am trying to do is,
i want to do double.TryParse for double column, and if there is any value with it then it will store dbnull value in corresponding rows,
same thing i will do for date, int
since my data table could have 100000 records so i don't to run loop for each row
is it possible through linq or with any method
Thank You
LINQ is not good for batch operations. You should create a stored procedure in your DB and import it in your model (If you are using EF that is import function, if using LINQ to SQL then a simple drag and drop will do it).
LINQ is no silver bullet for all problems where you need to loop over a (maybe very large) set of data. So if you want to go over each data set and change the values depending on some condition, a foreach loop is your friend.
LINQ is a query language to retrieve data and not some kind of super-fast way to alter large lists or other enumerable objects. It comes in handy if you want to get data from a given object applying some conditions or doing a GroupBy without ending up in a 20-lines unreadable mash of foreach-loops and if-statements.
It doesn't matter if you'll do it in a loop or with linq, you'll still need to iterate over the entire data table ...
there's no silver bullet that will save you from doing the checks and inserts i'm afraid

Too many parameters were provided in this RPC request. The maximum is 2100.?

A search query returned this error. I have a feeling its because the in clause is ginormous on a subordinant object, when I'm trying to ORM the other object.
Apparently in clauses shouldn't be built 1 parameter at a time. Thanks ibatis.
Your best bet is to revise your application to pass less than 2100 parameters to the stored procedure. This is a DBMS limit that can't be raised.
I got this same error when using an apparently innocent LINQ to SQL query. I just wanted to retrieve all the records whose ids were amongst the ones stored in an array:
dataContext.MyTable.Where(item => ids.Contains(item.Id)).ToArray();
It turned out that the ids array had more than 2100 items, and it seems that the DataContext adds one parameter for each item in the array in the resulting SQL query.
At the end it was a bug in my code, since the ids array had not to have so many items. But anyway it is worth to keep in mind that some extra validation is needed when using such constructs in LINQ to SQL.
You can do a few things:
Pump the params into a temp table and use said temp table to filter your query. See https://stackoverflow.com/a/9947259/37055
Create a comma-delimited array, and pass the array into SQL Server as a varchar(x). Split it out via TSQL (here are a few methods) and use the resulting rowset to filter your search results.
Have a look at your application logic. It's more than a little strange to be passing 2100 parameters to a stored procedure.
If you are passing 2100 parameters to a single stored procedure, you are simply doing something wrong. Don't raise the limit or try to work around this abomination, figure out how to do things right.

Quickest way to run SQL on a multidimensional array

I want to take a table as represented by a multidimensional string array (column names in another array) and use a SQL SELECT statement to get a subset of rows.
The Catch:
the table is input by the user (different table each time)
the SQL is also input by the user
Do I need to:
Create a table in SQL
Populate the table in SQL
Query the table
or is the a simpler solution? E.g. converting the multidimensional array to a DataTable and then running the SQL on that object?
I think you would be able to use DataTable for this. It's normally used to store data retrieved from a database but you can populate it manually. The best part is the DataTable.Select() method, which allows you to write just the WHERE clause of a query and it will return the matching rows.
You can create your own expression tree representing the query the user enters. This is how Linq works, under the hood. If you could give an example of what your trying to achieve it may help also what your going to write the application in c# for web for example.
For instance if you letting your users enter new rows, in some kind of GUI to a table then you could, do this in a datagrid and enable column filter to achieve the result mentioned above?
In a web app you could have an input box above each column users can enter data to filter that column on.

Categories

Resources