Expose stored procedure using oData service - stored-procedures

I need to expose my stored procedure using oData. I have done it using EclipseLink JPA but without odata. Any link to the tutorial or an example will be appreciated.

The best way to expose a stored procedure, will be to create a corresponding FunctionImport for it.
You can create a complex type, that corresponds to the return structure of your procedure, and map the input variables of the procedure to the FunctionImport input parameters.
Note: OData 4 defines something similar called ActionsImports too. The the only difference is, that ActionImports are "side effecting"
If you are using OData 4 and your procedure is changing some data you should use an ActionImport else, if its just reading the data and returning some results use FunctionImport.
If you are using OData 2 and you have a side effecting procedure, You should use a Function Import with IsSideEffecting flag set to true;
Links to implementation documents
Olingo 2: Adding Function Imports to OData Services with the JPA Processor
Olingo 4: How to build an OData Service with Olingo V4
Part 6: Action Imports and Function Imports

Related

Entity Framework Core Database Table Valued Functions Mapping

I use EFCore 2.1 Database First approach. I'm pretty familiar with SQL syntax and prefer build queries myself rather then leave this work on EF. I use Table Valued and Scalar Functions for querying the database.
I found this for Scalar
https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-2.0#database-scalar-function-mapping
But unfortunately nothing about Table Functions.
Is there any way to force Visual Studio grab all Table Functions and Scalar Functions and Stored Procedures from SQL Server, when I run Scaffolding?
I was using LINQ to SQL dbml designer before. Everything was extremely simple with dbml. You drag from Server Explorer drop to dbml and boom, I can use SQL Function or SP like regular C# method.
Any chance to reproduce this in EFCore?
There's no reverse engineer (aka DbContext scaffolding) support for it, but you can use FromSql() to query using table-valued functions. See these docs.
var searchTerm = "EF Core";
var blogResults = db.Blogs.FromSql(
"SELECT * FROM dbo.SearchBlogs({0})",
searchTerm);
Source : https://www.allhandsontech.com/data-professional/entityframework/entity-framework-core-advanced-mapping/
Use HasDbFunction to do a mapping, refer Microsoft doc
It requires return types to be declared as Keyless entity using HasNoKeyMicrosoft doc
Configure EF Context to expose Db function
modelBuilder.HasDbFunction(typeof(SalesContext)
.GetMethod(nameof(NameAndTotalSpentByCustomer)))
.HasName("CustomerNameAndTotalSpent");
modelBuilder.Entity<CustWithTotalClass>().HasNoKey();
Invoke Db function in calling code
_context.NameAndTotalSpentByCustomer().Where(c=>c.TotalSpent>100).ToList();
Generated SQL
SELECT [c].[Name], [c].[TotalSpent]
FROM [dbo].[CustomerNameAndTotalSpent]() AS [c]
WHERE [c].[TotalSpent] > 100

Call stored procedure with parameters using Web Api Odata

Is it possible to call Stored Procedure with parameters using Web Api Odata?. How can I achieve that?. My intention is call Web APi Odata function with two parameters to get results I'am expecting. I was thinking about using "Views", but unfortunately i have to pass parameters to get more specific results. Thanks for advise!
Expose your stored procedure as an unbound OData function. An OData function is invoked using GET with the parameters specified in the URI. For example:
GET http://host/SomeFunction(Param1=123,AnotherParam='a string')
You will need to declare the function as part of your OData configuration, and write a controller action method to implement the stored procedure invocation. Here's a tutorial to get you started: Actions and Functions in OData v4 Using ASP.NET Web API 2.2

Change precision of RFC parameter in OData service builder?

I am using SAP function BAPI_TRADINGCONTRACT_GET_LIST in which there is property reqquality whose type is edm.decimal, precision is 13 and scale 3. I want to edit it, but can't do it. How can I change the scale value to 2?
Or how can I edit a property of the RFC module?
Or any other procedure to handle the properties?
This depends on whether the Odata model is a custom one or if you are using an existing SAP delivered one (in the SAP namespace).
If you are using a SAP standard one, I would check if SAP has provided a Business Add In (BADI) to enhance the metadata model and associated data provider - for common Odata models SAP provides extension capabilities, here I would just add a new field and set it to the precision you require.
If the above is not available you could create a new Odata Model (using transaction SEGW) and wrap the function as per this tutorial - http://scn.sap.com/people/volker.drees/blog/2012/10/26/step-by-step-guide-to-build-an-odata-service-based-on-rfcs-part-1
Good Luck..

Using Breeze for arbitrary server response

Have all a structure for creating complex queries and obtaining data on the client side using Breeze and webapi IQueryable<T>.
I would use this structure on the client side to call another webapi controller, intercept the result of the query, and use this to make an Excel file returned by HttpResponseMessage.
See: Returning binary file from controller in ASP.NET Web API
How can I use the executeQuery without getting return data in standard Breeze JSON and without interfering with the data on the client side cache to have the 'octet-stream'.
The goal is to create an 'Export to Excel' without existing frontend paging for a large volume of data.
If you don't want to track changes, call EntityQuery.noTracking() before calling executeQuery(). This will return raw javascript objects without breeze tracking capabilities.
You can't make executeQuery() return binary 'octet-stream' data. But you can use breeze ajax implementation:
var ajaxImpl = breeze.config.getAdapterInstance("ajax");
ajaxImpl.ajax() // by default it is a wrapper to jQuery.ajax
Look http://www.breezejs.com/documentation/customizing-ajax
Create a custom "data service adapter" and specify it when you create an EntityManager for this special purpose. It can be quite simple because you disable the most difficult parts to implement, the metadata and saveChanges methods.
You don't want to cache the results. Therefore, you make sure the manager's metadata store is empty and you should add the " no caching" QueryOption. [exact names escape me as I write this on my phone].
Make sure these steps are really adding tangible value
Specialized server operations often can be performed more simply with native AJAX components.
p.s. I just saw #didar 's answer which is consistent with mine. Blend these thoughts into your solution.

breezejs + entity framework: how to round-trip ad-hoc properties

I'm using breezejs with an entity framework 5 model. The model is the old-school edmx/objectcontext style- not the newer dbcontext/poco style.
The model is shared with some wcf ria services domain services so I cannot switch to entity framework 6 or poco style entity framework at this time.
When using wcf ria services, if you wanted to add a property to an entity beyond what is generated by entity framework you could create a partial class, define the property and annotate it with the datamember attribute. Wcf ria services treats this new property like any other property and sends it to the client from the server and back to the server.
Is there a way to do the same thing with breezejs? Without moving entirely away from the automatic metadata generation goodness that comes with using entity framework?
Using fiddler I can see the property I want exposed is transmitted to the client during a query request.
I've looked at the documentation here http://www.breezejs.com/documentation/extending-entities but none of the examples seem to fit this scenario.
Breeze supports unmapped properties, these are properties that are declared on your javascript constructor that cannot be matched to any property in metadata. By default these properties are both persisted locally and sent to the server on a save. This is described in the link you mentioned:
http://www.breezejs.com/documentation/extending-entities
var Customer = function () {
this.myUnmappedProperty = "anything22";
};
myEntityManager.metadataStore.registerEntityTypeCtor("Customer", Customer);
These values will be available on the server after a SaveChanges call via the 'UnmappedValuesMap' property on each EntityInfo instance.
var unmappedValue = entityInfo.UnmappedValuesMap["myUnmappedProperty"];
What is sounds like you are looking for is "unmapped" properties to go in the "other" direction, i.e. from the server to the client. What might work for that but we haven't tried is adding a property to your server side EF class ( via the partial class mechanism) and mark it up for Json serialization. It "should" then get serialized down to the client, even though it won't show up in Metadata.
If this does NOT work, please post back here and we will consider it as a breeze feature request. The basic idea does make a lot of sense and we should support it.

Resources