We should provide a simple mechanism to execute queries/commands such as regular stored procedures that contain a SELECT statement. What FromSql() does won't work for those because you cannot used them as sub queries.
A few things we could use:
FromSql() but switch composition to in-memory if subsequent LINQ operators are applied. Same warning and kill switch for query evaluation we have talked about having for other queries would apply to these.IEnumerable<T> but a new type that implements GetEnumerator() and AsEnumerable()FromSql() (which is pretty standard although no longer required) for SQL Server as an indication that what follows is a non-composable stored procedure and that needs to go through a different execution mode (e.g. the one described in (1) or the one described in (3)). See here for some ways to make it work: http://stackoverflow.com/questions/1492411/sql-server-select-from-stored-procedure
We should consider providing an optional argument allowing specification of a SQL statement that would be run just before the actual SQL query. This would allow for things like declaring TVVs and temp tables etc. that could then be referenced from the query.
We had another conversation around this:
If we add the ability in the value reader to infer a map between field names and field positions on first execution, we can execute stored procedures as well as raw SQL queries without any modification or wrapping as long as they have not been composed over using LINQ.
We see this as a good thing: it will very likely be more performant/scalable for stored procedures because it avoids buffering the results on the server, and it avoids fiddling with the user query for raw SQL, making FromSql() without composition equivalent to the old SqlQuery().
If LINQ operators are applied then we can:
@divega We do this already at query compile time for TPH shapers: https://github.com/aspnet/EntityFramework/blob/dev/src/EntityFramework.Core/Metadata/Internal/EntityMaterializerSource.cs#L75
We don't need to change value reader itself as this is easily achieved by wrapping the underlying value reader in an index re-mapping decorator.
However, a likely better approach is to just delay shaper construction until query run time. An easy way to do this would be to generate a shaper stub into the query execution function.
Sounds great. Let's chat about it in more detail with @mikary when you are around.
Added logic for forcing client evaluation on stored procedures in #2053
Still need to update materialization to address out of order and extra columns.
Materialization issues for stored procedures was fixed by 4f05fbfed3bfddf5228b82e21c8e535b9f1d8775
How to pass "named" parameters in FromSql()?
Example:
object[] sqlParams = {
new SqlParameter("@Id", 45),
new SqlParameter("@Name", "Ada")
};
var UserType = dbcontext.Set
If SqlParameter is not supported then something like this would suffice:
var parameterDictionary = new Dictionary
{
{"@Id", 45},
{"@Name", "Ada"}
};
@mikary can you reply?
We don't currently have support for named parameters in FromSql and ExecuteSqlCommand. There are plans to support other patterns in the future (i.e. SqlParameter, DbParameter, anonymous types), but for now you should be able to use the somewhat clunky pattern that we use in FromSqlSprocQuerySqlServerTest:
var userType = dbContext.Set().FromSql("dbo.SomeSproc @Id = {0}, @Name = {1}", 45, "Ada");
Hi,
Is there a support to execute a stored procedure that returns multiple result sets?
Not at this stage, you would need to drop down to ADO.NET for that
Hi Rowanmiller - Is there a plan to resolve support to execute a stored procedure that returns multiple result sets? (or) Is that already resolved?
Hi Rowanmiller - Did you had a chance to check this? I am curious because I see some serous performance gains.
@tiwariarvin - We will support multiple result sets in the future, but at this stage there is no support for them. Stored procedure support in general is tracked by https://github.com/aspnet/EntityFramework/issues/245.
Thanks, will keep an eye.
I have made this to call stored procedure and map the DataReader to a specified model. I hope it helps.
Most helpful comment
I have made this to call stored procedure and map the DataReader to a specified model. I hope it helps.