Calling functions in a LINQ query - entity-framework

My question is that how to call a function in LINQ query? e.g
source.Where(x=> double.Parse(x.Col1)==3)
or
source.Where(x=> AnyUserFunction(x.Col1)==true)
Basically my requirement is to check weather Col1 is a numeric value or not, but I occasionally need to call my User Defined functions as well.

The problem is that your Linq to Entities provider doesn't know how to translate your custom methods to SQL. The solution proposed by #teovankot is the easy way to solve this problem, but if you want to work with Linq to Objects I suggest you use AsEnumerable extension method instead ToList because AsEnumerable does not execute the query until you consult the data, it preserves deferred execution, but be careful, try to don't use AsEnumerable or ToList on the entire DbSet because you'd retrieve all rows of that table affecting your application's performance.
Now if you only want to check weather Col1 is a numeric value or not, another solution could be using SqlFunctions.IsNumeric method which is translated into native SQL:
using System.Data.Entity.SqlServer;
//...
source.Where(x=> SqlFunctions.IsNumeric(x.Col1)==1);
You can find another set of functions you can also call in the DbFunctions static class.SqlFunctions are SQL Server specific, whereas DbFunctions aren't.

You can't call user defined functions easy in linq to sql.
But you can do it after you get all your data from DB to your server. Like this:
source.ToList().Where(x=> AnyUserFunction(x.Col1)==true)
Note ToList() call. this will get all your data from DB so you basically working with linq to objects where you can easy use your user defined fucntions.

Related

Possible to call a stored procedure on a Table-Per-Hierarchy table in EF Core 3.1?

I'm moving from EF Core 2.2 to 3.1. One breaking change (#15392) was that it no longer composed over stored procedures, so you had to add 'AsEnumerable'. That usually works, but I have a stored procedure call on a TPH table where that fails:
My call to the SPROC is:
SqlParameter authorizedUserID_p =
new SqlParameter("#authorizedUserID", authorizedUser.ID);
IEnumerable<Post> query =
context.Posts.FromSqlRaw<Post>("Post.USP_ReadPost #ID, #AuthorizedUserID",
parameters: new[]{ parentID_p, authorizedUserID_p }
).AsEnumerable<Post>();
Post targetPost = query.ToList<Post>().FirstOrDefault<Post>();
And it produces this error, recommending using AsEnumberable (which I'm already using above):
System.InvalidOperationException: FromSqlRaw or FromSqlInterpolated was called with non-composable SQL and with a query composing over it.
Consider calling AsEnumerable after the FromSqlRaw or FromSqlInterpolated method to perform the composition on the client side.
I believe the reason is because my Posts table is Table-per-hiearchy, as other calls to SPROCS in the same application are working fine. Would appreciate any help possible!
This is yet another issue introduced by EFC 3, tracked by #18232: Impossible to use stored procedures related to entities that inherits another one.
The reason is that SP calls are not composable, and EF Core always try to compose SQL for TPH base entities in order to add discriminator condition. Similar to Global Query Filters, but there you can at least use IgnoreQueryFilters, while here you have no option.
The good news is that it's already fixed in EFC repository. The bad news is that it won't be released until EFC 5.0.
Since AsEnumerable() doesn't help, all you can do is to wait for EFC 5.0. Or, if possible, convert SPs like this to TVF (table valued functions) which are composable. In general, use scalar functions or stored procedures with output parameter(s) for non query returning calls (to be executed with ExecuteSql*), and table valued functions for single query returning calls (to be used with FromSql*). Note that currently EFC does not support multiple query returning stored procedures anyway.

When is IEnumerable preferred over IQueryable in Entity Framework?

I understand how IEnumerable and IQueryable works. I just cannot imagine a situation where IEnumerable would be needed in entity framework when working with SQL database. I wonder if I can just discard IEnumerable in EF. Can you provide any useful example that shows IEnumerable could be more useful than IQueryable?
There are three situations that come to mind.
When EF cannot convert your query into a correct SQL statement - so you need to bring the results into memory to complete the computation.
When you need to perform operations that involve operators that do not convert to SQL.
When SQL server is slower at producing the computation than an in-memory calculation. Many times I have found that pulling all the data into memory is quicker than letting SQL to do it.
Provided a data source (as IQueryable) can be queried, then yes, use IQueryable - though you shouldn't be creating IQueryable instances or implementing it yourself, that's what EF is for. You will still need to use IEnumerable as method parameters or return types if you're using EF with external data-sources or other data that isn't queryable itself, such as JOINing an EF table with non-EF data.
For example, you'd have a return type as IEnumerable<T> if the data you're returning isn't queryable because you called AsEnumerable or ToList but you don't want to reveal implementation details - but I'd then prefer IReadOnlyList<T> in that case.

Generic way to insert some data into a table

I have always been using nhibernate ORM for inserting data to sql tables from application.
But recently I tried reading on Ado.net and found suggestion to use stored proc instead of
sqlcommand.executenonQuery().
In that case, every table insertion will need a different stored proc . A 100 table application will need 100 Stored procs. Is my understanding correct or is there a better way of doing it in a more generic way?
Please suggest.
A simple one-liner command can be an INSERT given directly in .NET code via parameterized Command class. Something like:
using (SqlConnection sqlConn = new SqlConnection(connectionString)) {
using (SqlCommand sqlCmd = new SqlCommand("INSERT INTO MyTable (Field1, Field2) VALUES (#Param1, #Param2)", sqlConn)) {
sqlCmd.Parameters.AddWithValue("#Param1", someValue1);
sqlCmd.Parameters.AddWithValue("#Param2", someValue2);
sqlConn.Open();
sqlCmd.ExecuteNonQuery();
}
}
So it doesn't have to be a stored proc for every command. You can have a class or classes dedicated to DB access only (db access layer) and populate it with various methods to read/write from DB. You can even have a generic method that automatically derives parameters for INSERT/UPDATE commands.
Of course if it's more than 1-2 commands or some logic is involved - that asks for a stored procedure.
Btw, this is my personal opinion, but i think ORMs are evil.
Have you heard about dapper, a powerful tool to execute a query and map the results to a strongly typed List. Dapper also support stored procedures, check this out.
Example:
dbConnection.Query<return type>("yourSP", parameters,
commandType: CommandType.StoredProcedure).First();
Also take some time to check this SO question.
Personally I would use an ORM if I have more than 5 different tables to select and/or insert into. Why should you walk 100 miles if the bus stop is right infront of the door?
That said the ORM is a generic way to access data. If you would want to code everything by hand, you could surely write stored procedures with optional parameters, but I don't recomend it.

When to use which Zend_Db class? Zend_Db_Select vs. Zend_Db_Table_Abstract

I think it's possible to write select queries with either Zend_Db_Select or Zend_Db_Table_Abstract, but I don't understand when to use which of the two.
Is one more optimized for something than the other? Are joins "easier" with one or the other?
Thanks!
There are a few different options in producing queries, for historical reasons.
In early versions of Zend Framework, Zend_Db_Tables had a method fetchAll with parameters where, order, offset and limit which you could use to fetch rows from a table. Developers soon found limitations with this approach. How would you add a GROUP BY clause?
Zend_Db_Select was invented to solve this problem, and you'll notice that since ZF 1.5, the fetchAll and related methods accept a Zend_Db_Select instance as the first parameter. Using the other parameters of fetchAll is now deprecated and you should pass in either an SQL string or a Zend_Db_Select object.
A Zend_Db_Select is simply a programmatic interface for building an SQL query. It's great for changing parts of the SQL based on user input or different factors, as instead of manipulating strings, you can just change the method calls and arguments.
Zend_Db_Table will return a Zend_Db_Table_Select (a Zend_Db_Select subclass) instance with its table name predefined if you call its select method - this is about the only difference between Zend_Db_Select and Zend_Db_Table_Select.
Your consideration really is whether to use Zend_Db_Select or to write SQL manually. Zend_Db_Select isn't infinitely flexible but it is easy to read, manipulate and work with.

Entity Framework - Get Object as Collection

Is it possible to get a collection (Dictionary) out of an Entity Object? I need this in order to pass parts of the Properties of the object to a function that needs an IDictionary.
Use:
Context.EntitySetName.AsEnumerable().ToDictionary(o => o.Key, o => o.Value);
Some detail on this:
ToDictionary is not supported in LINQ to Entities. This means that LINQ query string containing ToDictionary will compile, but will not execute, because the Entity Framework does not know how to translate them into SQL. Therefore, you have to execute the query on the database server first. So you have to project your set into a list first, which enumerates the entity set. AsEnumerable will do that. Obviously, if the entity set is large, you probably don't want to do this with the whole thing. Use a Where call or a LINQ query to reduce the result set to only the items you want in the dictionary first.
I don't think I fully understand your question. I don't know of any way of binding your database tables to IDictionary properties if that is what you are referring to, but you should be able to create whatever properties or methods you need to build a dictionary, and pass that. Is writing a business object method not an option for some reason?