WCF - OData: How to access an operation - c#

I am using a child class of the System.Data.Services.Client.DataServiceContext gerated by the "adding a Service Reference" in VisualStudio to access data via an OData service. The definition in the $metadata.xml of the service includes a custom operation:
<schema Namespace="dotNetBF.OData" xmlns="http://schemas.microsoft.com/ado/2006/04/edm">
<EntityContainer Name="OData" m:IsDefaultEntityContainer="true">
<EntitySet Name="SewageArea" EntityType="GeoMan.SealingRegister.SewageArea" />
<EntitySet Name="LandParcel" EntityType="GeoMan.SealingRegister.LandParcel" />
...
<AssociationSet Name="GeoMan_SealingRegister_SewageArea_LandParcel_GeoMan_SealingRegister_LandParcel_LandParcelPartnerSet" Association="GeoMan.SealingRegister.GeoMan_SealingRegister_SewageArea_LandParcel_GeoMan_SealingRegister_LandParcel_LandParcelPartner">
<End Role="LandParcelPartner" EntitySet="SewageArea" />
<End Role="LandParcel" EntitySet="LandParcel" />
</AssociationSet>
...
<FunctionImport Name="LandParcelByRegistrationYear" EntitySet="LandParcel" ReturnType="Collection(GeoMan.SealingRegister.LandParcel)">
<Parameter Name="registrationYear" Mode="In" Type="Edm.String" />
</FunctionImport>
</EntityContainer>
</Schema>
How can I access the defined function LandParcelByRegistrationYear through the DataServiceDeviceContext, commit a value for parameter registrationYearand consume the result.
I already imported the $metadata.xml but cannot find a method given the name of the operation.

Related

How to transform XML configuration pre-build?

I've got a solution:
Solution1
--ConfigProject
----AppManifest.xml
----ServiceManifest.xml
--Project1
--Project2
ServiceManifest.xml looks like this:
<ServiceManifest>
...............
<Resources>
<Endpoints>
<!-- This endpoint is used by the communication listener to obtain the port on which to
listen. Please note that if your service is partitioned, this port is shared with
replicas of different partitions that are placed in your code. -->
<Endpoint Protocol="https" Name="ServiceEndpoint" Type="Input" />
</Endpoints>
</Resources>
</ServiceManifest>
Without relying on c# code, is there a pre-build step that I can add that will transform the Resources section in the ServiceManifest file, based on a setting in the AppManifest.xml file?
You could describe your service manifest as following:
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="Stateless1Pkg" ServiceManifestVersion="1.0.0" />
<ConfigOverrides />
<ResourceOverrides>
<Endpoints>
<Endpoint Name="ServiceEndpoint" Port="[Port]" Protocol="[Protocol]" Type="[Type]" />
<Endpoint Name="ServiceEndpoint1" Port="[Port1]" Protocol="[Protocol1] "/>
</Endpoints>
</ResourceOverrides>
<Policies>
<EndpointBindingPolicy CertificateRef="TestCert1" EndpointRef="ServiceEndpoint"/>
</Policies>
</ServiceManifestImport>
Now you can apply the parameters in your ApplicationManifest. If you want you can add them a default value.
<Parameters>
<Parameter Name="Port" DefaultValue="" />
<Parameter Name="Protocol" DefaultValue="" />
<Parameter Name="Type" DefaultValue="" />
<Parameter Name="Port1" DefaultValue="" />
<Parameter Name="Protocol1" DefaultValue="" />
</Parameters>
You can override these parameters with an own customized ApplicationParameters file (like Local1.1Node.xml and Local.5Node.xml). Another alternative would be to insert the parameters per powershell during publishing:
PS C:\> New-ServiceFabricApplication -ApplicationName fabric:/myapp -ApplicationTypeName "AppType" -ApplicationTypeVersion "1.0.0" -ApplicationParameter #{Port='1001'; Protocol='https'; Type='Input'; Port1='2001'; Protocol='http'}
For further details:
https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-service-manifest-resources

Is it possible to have multiple controllers for a single entity type?

I have an entity framework model. Let's say we have an object Foo and an object Bar. They are related, so Foo has a navigation property to Bar, and vice versa.
Now, for my OData endpoint, I'd like to have two collections available for Foo, for instance declared like so:
var builder = new ODataConventionModelBuilder { Namespace = "Test" };
builder.EntitySet<Foo>("Fools");
builder.EntitySet<Foo>("Footballs");
builder.EntitySet<Bar>("Bars");
The idea here is that access to Fools would go through the FoolsController and access to Footballs would go through the FootballsController, so that I could return different sets of data in each endpoint.
Trying to do this, however, causes the following NotSupportedException error message:
Cannot automatically bind the navigation property 'FooThing' on entity type 'Foo' for the entity set or singleton 'Bars' because there are two or more matching target entity sets or singletons. The matching entity sets or singletons are: Fools, Footballs.
I sort of understand the issue, but if I know for a fact that only Footballs will have Bars, is there a way for me to help the system understand that Bars will only have Footballs?
The answer is absolutely yes.
There are many fluent APIs that you can call to set the binding manually, then to suppress the convention binding. For example:
HasManyBinding
HasRequiredBinding
HasOptionalBinding
HasSingletonBinding
...
Based on your information, you can call the following to make the binding manually:
builder.EntitySet<Bar>("Bars").HasRequiredBinding(b => b.FooThing, "Fools");
I also create a simple Foo and Bar class model to test. The below result shows the metadata:
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
<edmx:DataServices>
<Schema Namespace="WebApiTest" xmlns="http://docs.oasis-open.org/odata/ns/ed
m">
<EntityType Name="Foo">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Int32" Nullable="false" />
</EntityType>
<EntityType Name="Bar">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Int32" Nullable="false" />
<NavigationProperty Name="FooThing" Type="WebApiTest.Foo" Nullable="fals
e" />
</EntityType>
</Schema>
<Schema Namespace="Test" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityContainer Name="Container">
<EntitySet Name="Fools" EntityType="WebApiTest.Foo" />
<EntitySet Name="Footballs" EntityType="WebApiTest.Foo" />
<EntitySet Name="Bars" EntityType="WebApiTest.Bar">
<NavigationPropertyBinding Path="FooThing" Target="Fools" />
</EntitySet>
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
As you can see, "HasRequiredBinding" can make the navigation property as non-nullable, while, "HasOptionBinding" can make it nullable.
Hope it can help. Thanks.

Invalid cast exception is raised when insert is performed into column of type SYSTIMESTAMP WITH TIME ZONE with default value

Could you please assist with next:
I have a table with column of type SYSTIMESTAMP WITH TIME ZONE and with default value - SYSTIMESTAMP. I use Entity Framework 5 database first. When I try to insert entity in this table I get an exception. The exception message is “A store-generated value of type 'System.DateTime' could not be converted to a value of type 'System.DateTimeOffset' required for member 'INSERT_DATE' of type 'Model.SAMPLE'.”. The inner exception message is: “Invalid cast from 'System.DateTime' to 'System.DateTimeOffset'.”
I use ODAC 12.1012 unmanaged driver.
How should I solve this problem?Sample table script:
CREATE TABLE "TEST"."SAMPLE"
( "ID" NUMBER NOT NULL ENABLE,
"INSERT_DATE" TIMESTAMP (6) WITH TIME ZONE DEFAULT systimestamp,
"TEXT_COLUMN" VARCHAR2(200 BYTE),
CONSTRAINT "SAMPLE_PK" PRIMARY KEY ("ID")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "SYSTEM" ENABLE
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "SYSTEM" ;
edmx file content:
<edmx:Runtime>
<!-- SSDL content -->
<edmx:StorageModels>
<Schema Namespace="Model.Store" Provider="Oracle.DataAccess.Client" ProviderManifestToken="11.2" Alias="Self" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns:customannotation="http://schemas.microsoft.com/ado/2013/11/edm/customannotation" xmlns="http://schemas.microsoft.com/ado/2009/11/edm/ssdl">
<EntityType Name="SAMPLE">
<Key>
<PropertyRef Name="ID" />
</Key>
<Property Name="ID" Type="number" Precision="38" Scale="0" Nullable="false" StoreGeneratedPattern="Identity" />
<Property Name="INSERT_DATE" Type="timestamp with time zone" Precision="6" StoreGeneratedPattern="Identity" />
<Property Name="TEXT_COLUMN" Type="varchar2" MaxLength="200" />
</EntityType>
<EntityContainer Name="ModelStoreContainer">
<EntitySet Name="SAMPLE" EntityType="Self.SAMPLE" Schema="TEST" store:Type="Tables" />
</EntityContainer>
</Schema>
</edmx:StorageModels>
<!-- CSDL content -->
<edmx:ConceptualModels>
<Schema Namespace="Model" Alias="Self" annotation:UseStrongSpatialTypes="false" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns:customannotation="http://schemas.microsoft.com/ado/2013/11/edm/customannotation" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
<EntityContainer Name="vm2" annotation:LazyLoadingEnabled="true">
<EntitySet Name="SAMPLE" EntityType="Model.SAMPLE" />
</EntityContainer>
<EntityType Name="SAMPLE">
<Key>
<PropertyRef Name="ID" />
</Key>
<Property Name="ID" Type="Decimal" Nullable="false" Precision="38" Scale="0" annotation:StoreGeneratedPattern="Identity" />
<Property Name="INSERT_DATE" Type="DateTimeOffset" Precision="9" annotation:StoreGeneratedPattern="Identity" />
<Property Name="TEXT_COLUMN" Type="String" MaxLength="200" FixedLength="false" Unicode="false" />
</EntityType>
</Schema>
</edmx:ConceptualModels>
<!-- C-S mapping content -->
<edmx:Mappings>
<Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2009/11/mapping/cs">
<EntityContainerMapping StorageEntityContainer="ModelStoreContainer" CdmEntityContainer="vm2">
<EntitySetMapping Name="SAMPLE">
<EntityTypeMapping TypeName="Model.SAMPLE">
<MappingFragment StoreEntitySet="SAMPLE">
<ScalarProperty Name="TEXT_COLUMN" ColumnName="TEXT_COLUMN" />
<ScalarProperty Name="INSERT_DATE" ColumnName="INSERT_DATE" />
<ScalarProperty Name="ID" ColumnName="ID" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
</EntityContainerMapping>
</Mapping>
</edmx:Mappings>
</edmx:Runtime>
Thanks in advance!

EDMX file storage model is using self instead of fully qualified name

I am having issue with the EF generated edmx file where SSDL is using self instead of Fully Qualified Name but CSDL and MSL are having FQN.
Here is the snapshot of code
SSDL:
<Association Name="FK_CustomerOrders">
<End Role="Customers"
Type="self.Customers" Multiplicity="1">
<OnDelete Action="Cascade" />
</End>
</Association>
CSDL and MSL:
<Association Name="FK_CustomerOrders">
<End Role="Customers"
Type="ExampleModel.Store.Customers" Multiplicity="1">
<OnDelete Action="Cascade" />
</End>
</Association>
This is happening after we migrated solution from VS 2010 to VS 2013

How to write mappings for a stored procedure

There is an excellent post on how to map return values for a stored procedure call here:
http://elegantcode.com/2008/11/23/populating-entities-from-stored-procedures-with-nhibernate/
The mapping in this example has been done through hbm files.
I am trying to use the latest version of Nhibernate (3.2) where we can do mapping through code. I really want to find out the C# code that would create a mapping like below:
<sql-query name="GetProductsByCategoryId">
<return class="Product">
<return-property column="ProductID" name="Id" />
<return-property column="ProductName" name="Name" />
<return-property column="SupplierID" name="Supplier" />
<return-property column="CategoryID" name="Category" />
<return-property column="QuantityPerUnit" name="QuantityPerUnit" />
<return-property column="UnitPrice" name="UnitPrice" />
<return-property column="UnitsInStock" name="UnitsInStock" />
<return-property column="UnitsOnOrder" name="UnitsOnOrder" />
<return-property column="ReorderLevel" name="ReorderLevel" />
<return-property column="Discontinued" name="Discontinued" />
</return>
exec dbo.GetProductsByCategoryId :CategoryId
</sql-query>
To be honest I never tried it, by you should take a look to the extension method AddNamedQuery(..): you call it from you Configuration instance (NHibernate.Cfg namespace)).
Some examples on the NHibernate test project.
By the way, you can mix the new 3.2 mapping-by-code and xml one.
Start to look at this question;

Categories

Resources