Dynamics 2011 Intersect / Junction entity - rest

I have 3 entities.
PortalRole, Person and PersonPortalRole
PersonPortalRole is a intersection entity to deal with my Many-Many relationship.
I am using JavaScript through a HTML web resource to allow the creation and removal of this entity. I can create new entities by using the REST service fairly easily but I can't find a way of deleting a intersect record (two lookup fields) using the PersonId and PortalRoleId.
Has anyone had any exposure to either deleting a record through REST using the two foreign keys values from a lookup? I was trying to get the object first using a filter but can't seemt o filter using the lookup primary keys.
Was trying something like below which returns 15 entries to then filter the results to get the primary key, and then delete using that key but not sure on the way to do this.
SERVER/INSTANCE/XRMServices/2011/OrganizationData.svc/personportalrolesSet?$expand=Person,PortalRole

Based on that URI, you are interacting with an OData service. OData uses Atom feeds for returning lists of stuff so you will likely find within each <entry> element a <id> element that contains the URL of the resource. If you issue a HTTP DELETE to that URL then your resource will be deleted.
See docs here http://www.odata.org/developers/protocols/operations#DeletingEntries

I don't use the REST endpoint, but there's no way I know of to end a many-to-many relationship except through sending a Disassociate request (or if you have access to the SQL box, direct insertion/deletion in that table). MS has some sample code available that shows how to do this using the REST Endpoint.

Related

OData REST API where table has columns unique to customer

We would like to create an OData REST API. Our data model is such that each customer has their own database. All database objects have the same definition across all customer databases, with the exception of a single table.
The customer specific table we will call Contact. When a customer adds a column the system creates a column with a standardised name with a definition translated from options selected by the user in the UI. The user only refers to the column data by a field name they have specified to enable the user to be able to generate friendly queries.
It seems to me that the following approaches could be used to enable OData for the model described:
1) Create an OData open type to cater for the dynamic properties. This has the disadvantage of user requests for a customer not providing an indication of the dynamic properties that can be queried against. Even though they will be known for the user (via token authentication). Also, because dynamic properties are a dictionary, some data pivoting and inefficient query writing would be required. Not sure how to implement the IQueryable handling of query options for the dynamic properties to enable our own custom field querying.
2) Create a POCO class with e.g. 50 properties; CustomField1, CustomField2... Then somehow control which fields are exposed for use in OData calls. We would then include a separate API call to expose the custom field mapping. E.g. custom field friendly name of MobileNumber = CustomField12.
3) At runtime, check to see if column definitions of table changed since last check. If have, generate class specific to customer using CodeDom and register it with OData. Aiming for a unique URL for each customer. E.g. http://domain.name/{customer guid}/odata
I think the ideal for us is option 2. However, the fact the CustomField1 could be an underlying SQL data type of nvarchar, int, decimal, datetime, etc, there are added complications.
Has anyone a working example of how to achieve what has been described, satisfactorily?
Thanks in advance for any help.
Rik
We have run into a similar situation but with our entire dataset being unknown until runtime. Using the ODataConventionModelBuilder and EdmModel classes, you can add properties dynamically to the model at runtime.
I'm not sure whether you will have to manually add all of the properties for this object type even though only some of them are unknown or whether you can add your main object and then add your dynamic ones afterwards, but I guess either would be workable.
If you can get hold of which type of user it is on the server, you could then add only the properties that you are interested in (like option 3 but not having to CodeDom).
There is an example of this kind of untyped OData server in the OData samples here that should get you started: https://github.com/OData/ODataSamples/tree/master/WebApi/v4/ODataUntypedSample
The research we carried out actually posed Option 1 as the most suitable approach for some operations. i.e. Create an SQL view that unpivots the data in a table to a key/value pair of column name/column value for each column in the table. This was suitable for queries returning small datasets. This was far less effort than Option 3 and less confusing for the user than Option 2. The unpivot query converted the field values to nvarchar (string) values and thus meant that filtering in the UI by column value data types was not simple to achieve. (If we decide to implement this ability, I believe this can be achieved by creating a custom attribute that derives from EnablQueryAttribute, marking the controller action with it and manipulate the IQueryable before execution).
However, we wanted to expose a /Contacts/Export endpoint that when called would output the columns from a table with a fixed schema joined on a table with a client specific schema and output to a CSV file. All the while utilising the OData supported filter syntax. One of our customer databases has more than 12 million rows of data and is made up of approximately 30 columns.
To achieve this it looks like our best bet would have been to work with the Microsoft.OData.Core.UriParser.UriQueryExpressionParser class, unfortunately Microsoft in their wisdom have declared this as internal, as well as many of it's dependants.
Walking an abstract syntax tree built from OData supported query options and applying our own visitor to each node to build some dynamic Linq query/SQL seems like a possible solution.
For the time-being we will simply implement a cut-down set of supported $filter criteria without the support for grouping parenthesis.

Why is DELETE not supported on to-many-association resources in Spring Data REST?

I am using Spring Data REST. I am trying to unbind a collection association from an entity (item). i.e. - a property of the item is of List type. I want to remove all items from that List.
To do this, I am using the DELETE method:
curl -X DELETE …/categories/54ea0bcf27a2fb1b4641083a/fixedParentCategories
This gives me a 405 Method not allowed error code. But, it works for a single valued association (when it is not of List type). The documentation clearly lists DELETE as a supported method for associations. I'd like to know if there is a way around this. Also, I tried using PUT (Content-Type: text/uri-list) with an empty body, and it gives an error about missing request body. Other operations on this association are all working fine - I am able to add items to this collection, etc.
My entity looks like this:
#Document
public class Category {
#DBRef(lazy = true)
private List<Category> fixedParentCategories;
…
}
I just checked the code and you're right, we're actively rejecting DELETE requests for Maps and collections. The rationale is as follows:
An association that is of Map or collection must never be null in the domain model. Translating this into HTTP resources means that the resource will always be available and in the worst case return an empty representation (empty JSON array, or empty JSON object). Accepting a DELETE request would logically null the relationship in the domain model and thus lead to a state that contradicts the very first assumption.
We generally recommend to simply PUT an empty body with media type text/uri-list to the association resource to empty out the associations as that's semantically more correct. Consider it like the difference between truncating and dropping a database table.
If you think that should change and have good reasons that you can back your request with, feel free to open a ticket in our JIRA.

sailsjs delete/update multiple rows

I am working on sailsjs, I have generated api model and controller. I am just wondering if I can post and create many entries of this model instead of use curl in commandline over and over. also does this restful interface support a delete method and update method for multiple rows at once?
Thanks
Most of this information is in the docs http://sailsjs.org/#/documentation/reference/blueprint-api
You can create multiple records at once in a single post by default. Post an array of entries to create.
For update and delete, I believe you will need to tweak the blueprints to look for an array of ids. Waterline, the underlying ORM of Sails supports create and delete on multiple rows, though watch out for breaking associations http://sailsjs.org/#/documentation/reference/waterline/models/update.html?q=notes
In order to override blueprints, create your own blueprints in api/blueprints/ e.g. api/blueprints/update.js and make them look for an array of ids. You'll probably want to start with the default blueprints https://github.com/balderdashy/sails/tree/master/lib/hooks/blueprints/actions.
Also, you'll need to define your own routes as the update and delete actions are by default bound to the PUT 'controller/:id' and DELETE 'controller/:id' respectively, which inherently allows for only a single id.

Where do you create a custom model (DTO) in server code, such that Breeze can relate to EntityFramework entities?

I am developing a SPA using Angular-Breeze-WebAPI-EntityFramework.
Now Breeze uses the Entity Framework metadata information to create it's own Breeze models. We use this in our application for Breeze validation.
So far, it's all been nice and easy. Now we are having to create a search page (say for querying customers). The search can be by Customer.Name or by Product.Id (which would return a list of customers who have bought that product). The result is a ng-repeater, which displays Customer.Name, Order.LastPlaced etc.
if you are getting confused by the tables and columns, forget that. What I am only trying to get to is that, both the search object and the result object are not 1:1 with Entity tables (or objects). So obviously I feel the need to create a custom object (one for the search and one for the results). My question primarily is where and how do I create that object?
If I create it at the data layer, Breeze would have no idea of the metadata for each of the properties (since it uses EF for that).
I obviously can't create just a JavaScript object, since I will have to query the database (using EF) to search and populate the object.
So where does one create such a custom object (traversing multiple tables) such that Breeze still can figure out the metadata and perform validation and such when the need arises?
Thank you all.
You can create metadata on the client for types that the server either doesn't know about or doesn't have the schema for. See http://www.breezejs.com/documentation/metadata-by-hand.

wcf data service with Entity Framework

I am trying to create WCF Data service project using Entity Framework. ( I am new to both).
I created entities using DB.
Now, I created service operation, which returns the IQueryable<entity>.
My problem is
I do not want to return the entire set of columns in the entity. I cannot delete them from the entity as it is not null. How to avoid these?
I have few FK columns and I need other column details of the table. How to include columns from other table?
Why it is not possible to use POCO class to be returned from WCF Data service?
How do I format the response; i.e., add few more details to the response like page number etc, change the xml tags, remove few details like "link rel"?
I have tried a lot of things to achieve 1 and 2. But finally I realised that I can only use the entity as it is to make it work.
I have no idea about 4.
Any suggestions would be appreciated.
1. I do not want to return the entire set of columns in the entity.
2. I have few FK columns and I need other column details of the
table.
For this, you should define a new class that matches what you need / what you want your clients to see. That can be a straight POCO class - no special requirements. Assemble that class for each entity, leaving out the unwanted columns, and grabbing the extra field or two for the FK columns into that new class. Return an IQueryable<YourNewClass> instead of the entity class directly.
To avoid huge left-right-assignment statements just to fill the properties of the new class, you should have a look at AutoMapper which makes it really easy to copy around classes that are very similar to one another (e.g. missing or adding a few properties).
4. How do I format the response; i.e., add few more details to the
response like page number etc, change the xml tags, remove few details
like "link rel"?
That's not possible - the OData protocol very strictly defines what's going to be in the message, what links there are etc. If you can't live with that - you'll have to roll your own WCF REST service and drop the WCF Data Service stuff altogether.
Check out the WCF REST Developer Center on MSDN if you want to investigate that route more thoroughly.
Update: that link seems to have gone dead - try WCF Web Http Programming Overview instead.
Make sure you have an Id property or you specify either [Key] or [DataServiceKey("Your_Custom_ID_Property")]
For me this sorted out the issue