|
These are questions or issues with the new feature for 6.1.2.0 that adds output parameters to stored procedure calls to DevForce. Entity Framework already supported out parms but DevForce never did. The patch build I tested was 6.1.2.0(e).
At first when I installed the build and regenerated the models, nothing looked or acted differently but it built and ran and the SPs executed. However, still no values in the out parms. After a day or two of trying everything I could think of, I checked our T4 templates which extensively customize the normal T4s and we did in fact override a method that has changed (WriteEdmFunctionExecuteDefinition) so that we could add a 'virtual' keyword to allow testing SPs with disconnected entity managers. Since the method that this method called just added an extra overloaded signature with an extra "parameterModes" argument it still worked like before for the patch but it might have been better to force that to be a breaking change so it would be obvious.
Second, (and this has been the same even pre-patch), DevForce always generates all SP parms (in or in/out) as a nullable type where as in LinqPad using EF, I can type them as the non-nullable types they really are.
Here's the definition of an output parm in LinqPad for a SQL SP that just takes "int":
ObjectParameter ReturnValue = new ObjectParameter("ai_return_value", typeof(Int32));
|
Here's the definition DevForce generates:
System.Nullable<int> ai_return_value
|
Third, and I think this is a bug, you have to initialize the output parms to NULL prior to executing the stored procedure or you won't get any results back out of them. SQL server 2008 doesn't require this, EF doesn't require this but that's the only way it seems to work with DevForce.
Here's that same parm in LinqPad being set and EF happily returns data in it but when I do this from C#, the value never gets set to what the procedure returns:
Output parms that are System.String also have to be initialized to null; not empty string but null. But if the procedure doesn't set them to a non-null string (like '') on returning (typically for us, it's an error message output parm), you'll get an exception:
Exception Type: IdeaBlade.EntityModel.EntityServerException Message: Unable to cast object of type 'System.DBNull' to type 'System.String'.
Again, SQL server 2008 and EF don't have a problem with nullable values as out parms.
Next, as an FYI, calls to the SP function (when calling it on the Entity Server running sync) need to add the "ref" before the out parms but since the compiler will complain if you miss it, maybe in the doc you can just give a valid example like:
manager.GetSomeSPFunction(myInputParm, ref myOutputParm);
|
Lastly, I haven't been able to figure out how to call the same procedure from SL async. In the case where the SP doesn't return any collection (it only sets the output parms), you need to execute it with ExecuteQueryForObjectAsync but the xxxQuery method DevForce builds returns a StoredProcQuery and ExecuteQueryForObjectAsync wants an IEntityScalarQuery so you get a compile error. The sync version, ExecuteQueryForObject, takes an IEntityQuery.
Summary:
- Check your T4 templates for overrides of WriteEdmFunctionExecuteDefinition as it has new parameters on the method used to build the stored proc function/query. It would be nice if the release notes mentioned changes to any T4 method in the DevForce DomainModelTemplate.
- You have to initialize your local variables to NULL or you won't get values back.
- If you have a string out parm, the procedure can't leave it NULL (needs to be set to empty string) or you'll get an exception thrown.
- Can't seem to call these from SL Async (at least when it doesn't have a return collection)
|