Entity Framework and Stored PRocedures, how to remove Nullable paremeters - sql-server

Well I've been using Model-First with DbSet code generation. And now I what I want to do is to add some stored procedures.
But Code I get look like like:
public virtual ObjectResult<Nullable<int>> CountPostsInThread(Nullable<int> threadID, ObjectParameter postCount)
{
var threadIDParameter = threadID.HasValue ?
new ObjectParameter("threadID", threadID) :
new ObjectParameter("threadID", typeof(int));
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<Nullable<int>>("CountPostsInThread", threadIDParameter, postCount);
}
Now, how Do I get rid off all those ?
It's something wrong with tt files, or with my stored procedure ?
SP:
ALTER PROCEDURE dbo.sp_CountPostsInThread
(
#threadID int,
#PostCount int = 0 OUTPUT
)
AS
SELECT COUNT(*)
FROM PostSet
WHERE PostSet.ThreadID = #threadID

Nothing is wrong with the template or stored procedure. SP's parameters accept NULL value so because of that EF makes them nullable. The ternary operator is used because if you pass null EF must somehow pass the type of null parameter to correctly setup SqlParameter used internally.

Related

Table-valued parameter in stored procedure

It is my understanding that there is no elegant way to call a stored procedure in EF6 using table-valued parameters. Can someone verify or discredit my suspicion?
Table-valued type:
CREATE TYPE MyTestType AS TABLE
(
ID INT,
String VARCHAR(30)
);
Stored procedure:
CREATE PROCEDURE MyTestProc
#TestVar MyTestType READONLY
AS
BEGIN
SELECT * FROM #TestVar
END
C# EF call:
var testTable = new DataTable();
testTable.Columns.Add("ID", typeof (int));
testTable.Columns.Add("string", typeof (string));
testTable.Rows.Add(1, "Row1");
var parameter = new SqlParameter("#TestVar", SqlDbType.Structured);
parameter.Value = testTable;
parameter.TypeName = "dbo.MyTestType";
var results = dbContext.Database.SqlQuery<TestObject>("exec dbo.MyTestProc #TestVar", parameter).ToList();
The code above is working, I would just like to see if there is a more elegant way of executing it. I feel like I should be allowed to do something like
var results = dbContext.MyTestProc(testTable).ToList();
Edit
I came across this article which has a slightly cleaner way of handling the data table, but still hoping for a cleaner way to call my stored procedure with the table-valued parameter.
Code.msdn - Stored Procedure with Table-Valued Parameter in EF and ASP.NET MVC

What does a positive value for command.Parameters.IsDirty indicate?

I am trying to get some value in output parameters using SqlCommand Parameters.
The stored procedure runs fine, giving proper records. I verified it executing procedure on Sql Server as well to be sure I am doing it right.
Still, I'm not able to get output on server-side, it always comes nothing! While debugging, I see that IsDirty proeprty for command.Parameters is set to True.
Can anyone tell what does it indicate?
Here is some code :
command.Parameters.Add("#count", SqlDbType.Int).Value = initialCountValue
command.Parameters("#count").Direction = ParameterDirection.Output
Dim dr = command.ExecuteReader()
newCountValue = Convert.ToInt32(command.Parameters("#count").Value)
Here is procedure example:
CREATE PROCEDURE [dbo].[usp_some_procedure]
#filter INT
#count INT output
AS
BEGIN
DECLARE #filtered_ids TABLE(row_num INT IDENTITY(1,1), id INT primary key)
INSERT INTO #filtered_ids ( id )
SELECT id
FROM dbo.some_table
WHERE #filter = 0 OR table_field = #filter
ORDER BY id desc
SELECT #count = COUNT(*)
FROM #filtered_ids
SELECT some_table.*
FROM some_table
INNER JOIN #filtered_ids
ON some_table.id = #filtered_ids.id
END
Output parameters are not visible to the calling code while the reader is opened.
Close the reader that you opened with ExecuteReader, then read your value:
Using dr = command.ExecuteReader()
...
End Using
newCountValue = CInt(command.Parameters("#count").Value)
SqlCommand.Parameters is an instance of SqlParameterCollection. SqlParameterCollection does not have a publicly available member called IsDirty. If you are seeing one in your command.Parameters then it is not an instance of SqlParameterCollection which means that command isn't an instance of SqlCommand.
I did find what appears to be a decompiled version of the SqlParameterCollection class that seems to have an internal member called IsDirty, but you should not have access to this.
It seems to me that you are doing something weird here and it's entirely possible that is the cause of your problem. I would add the default System.Data.SqlClient namespace and see if that resolves your problem.
It might help to post more of your code including where you are getting your SqlCommand class from.

Calling a sql server stored procedure with output parameter when using Simple.Data

Using Simple.Data, I would like to get the result from an output parameter in a stored procedure. Let's say I have the following SP (disregard the uselessness of it):
CREATE PROCEDURE [dbo].[TestProc]
#InParam int,
#OutParam int OUTPUT
AS
BEGIN
SELECT #OutParam = #InParam * 10
END
When I call it with Simple.Data, I use the following code.
var db = Database.Open();
int outParam;
var result = db.TestProc(42, out outParam);
Console.WriteLine(outParam); // <-- == 0
Console.WriteLine(result.OutputValues["OutParam"]); // <-- == 420
It feels like outParam should contain the value, and not the OutputValues dictionary. So my question is: Is there a nicer way to get the result from OutParam in this particular case?
Unfortunately, out parameters are not supported by the dynamic binding infrastructure used by Simple.Data, as they are not supported in all CLR languages.
I am open to suggestions for better syntax, though.

problem with update using scalar function

i have created a function:
CREATE FUNCTION FindDistrictId (#param XML)
RETURNS INT
(...)
which i want to use in a stored procedure like that:
CREATE PROCEDURE UpdateDistinctID
AS
UPDATE Notices SET DistinctId = FindDistrictId(Notices.XmlContent)
WHERE DistinctId = 0
I get 'FIndDistrictId is not a recognized built-in function name' when i try to do that. I thought that maybe i can't do Set field = function() but then i checked here and i think it should work.. any idea why it's not? The function is created for sure im my db, i checked sys.object
You need to include the schema (owner if this is SQL 2000 or earlier) of the function on the call. By default, that would be dbo.
UPDATE Notices SET DistinctId = dbo.FindDistrictId(Notices.XmlContent)
WHERE DistinctId = 0

Subsonic 3 - Passing null value to stored procedure parameter

Using Subsonic 3.0.0.3 is it feasible to pass a null value to a stored procedures parameter? If so, what is the appropriate way?
Details
Say I have an sp where one of the parameters has a default value like:
CREATE Procedure Test_SPWithNullParams( #p1 int=null, #p2 varchar(50) )
AS
SELECT 1 as Stuff
Then in my code I want to do something like:
var db = new Sandbox.DB();
StoredProcedure sproc = db.Test_SPWithNullParams( null , "test");
//alternately --> db.Test_SPWithNullParams("test");
The way the corresponding function generated in StoredProcedures.cs, however, the parameter for #p1 is not nullable. So what are my alternatives? I came across this article (http://brianmrush.wordpress.com/2010/01/19/subsonic-t4-templates-stored-procedures-nullable-parameters) but it seems like a cumbersome work around that effectively branches the code base.
Alternatively I've thought about manually overriding the command object. Something like:
int dummyInt = -1;
StoredProcedure sproc = db.Test_SPWithNullParams( dummyInt , "test");
sproc.Command.Parameters[0].ParameterValue = DBNull.Value;
Thoughts?
I don't have Subsonic at hand, but perhaps you could use nullable int.
int? dummyInt = null;
StoredProcedure sproc = db.Test_SPWithNullParams( dummyInt , "test");
No way. Stored procedures are generated only with no nullable types. Why not try something like this?:
StoredProcedure sproc = db.Test_SPWithNullParams( someNullableInt.HasValue ? someNullableInt.Value: 0, "test");

Resources