OData Model not loaded? - odata

I am using an OData model in my SAP UI5 application. I do the following:
var oView = this.getView();
this._oModel = oView.getModel();
which I thought loaded the model and allowed me to access whatever I needed to inside the model. However whenever I try to get a property using getProperty(path) it returns undefined. I know the path is correct because I used it elsewhere in my application and it worked okay. The model I am using is named "metadata.xml" if that helps.

If you read the documentation provided by SAP talking about OData services (I assume v2), you might find your answer there. Since you are using getProperty(), "you can only access single entities and properties with these methods. To access entity sets, you can get the binding contexts of all read entities via a list binding." Therefore you may want to a read() of the entity set first and then use the results of this read to access whatever property you want.
Link to doc: https://sapui5.hana.ondemand.com/#docs/guide/6c47b2b39db9404582994070ec3d57a2.html

Related

Get another Entity while processing an Entity

I'am new in Olingo: sorry if my question is strange.
When Olingo service receive request to get entity of EntitySet_1 it calls method of custom entityProcessor (then processor call some storage object and send to it EdmEntitySet and List objects). But this processor method must get entity of EntitySet_2 to end processing. How i can realize getting entity of another entitySet? Or in other words: how can i get entity of another entitySet programatically (is it necessary to create new EdmEntitySet object? etc.) ?
Maybe some ideas, clever words...
Found only one solution: REST-request to the same service for entity of EntitySet_2 while processing entity of EntitySet_1.
Such feature should comes from the design itself. Calling same service from itself is not recommended.
What you should do is utilize the data access methods (ex:- database access method) you already have and get the required EntitySet_2 from it for processing.
For this you will need to create data access requests (ex:- SQL query for EntitySet_2) and map the results to create the EntitySet_2. As I said earlier, the design of your service should be flexible enough for this.

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.

Backbonejs updating Model with idAttribute set to Id

I'm trying to update a backbone model, the server side is asp.net mvc 4. I'm getting:
"System.ArgumentException: An item with the same key has already been added" exception.
The reason is because backbone is sending Id and id to the server as properties, and the JsonValueProvider tries to add this to a dictionary.
Here is my model:
var Task = Backbone.Model.extend({
url: "/tasks/task",
idAttribute: "Id"
});
This is send to the server via Put request:
{"Id":294912,"Task":"test","DueDate":"2012-03-24T02:00:00.000Z", "id":294912}
Is there a way to prevent backbone in sending the "id" property?
The problem here is because the conventions in C# is not the same as in JavaScript. In C# classes have properties that starts with capital letters (Pascal Case) and it's the norm in JavaScript to start your properties in lower case (Camel Case).
Thus when serializing view models the default behavior of the JSON.NET serializer is to serialize the object exactly with the same capitalization of properties. I could rename the properties on the view model to be camel case, but it would be as "weird" as to have properties with pascal case in your JavaScript objects.
So instead to force Backbone into a non convention way, I've change the serialization of the objects to convert the Pascal case properties into Camel case properties by leveraging JSON.NET's Contract Resolver functionality.
var settings = new JsonSerializerSettings();
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
JsonSerializer serializer = JsonSerializer.Create(settings);
JsonConvert.SerializeObject(object, Formatting.None, settings);
Now this creates consistency on the client side with my code and with all the cool libraries out there.
Sounds to me like the issue is in your server-side code, not with the call from Backbone. A PUT is an edit operation on the server, so you're updating an existing entity. You need the ID property to identify the model on the server and update the properties that have changed.
If ASP.NET MVC is complaining that the model already exists in the database, you are trying to do an INSERT instead of an UPDATE. We'd need to see the controller and data access code to see where things are going awry.
UPDATE: What happens if you leave off the idAttribute property? From the Backbone documentation:
A special property of models, the id is an arbitrary string (integer id or UUID).
If you set the id in the attributes hash, it will be copied onto the model as a
direct property.
The id attribute should be sent by default; it looks like you're forcing it to be included a second time.
Under idAttribute in the docs:
A model's unique identifier is stored under the id attribute. If you're directly communicating
with a backend (CouchDB, MongoDB) that uses a different unique key, you may set a Model's
idAttribute to transparently map from that key to id.
ASP.NET MVC's model binding should be able to cope with id vs. Id.
UPDATE: Found a good blog post that describes using a view model to aid in serializing your C# objects into the format Backbone expects. This seems like a reasonable, if slightly annoying, solution.

Introduce custom property in OData

In my database User table I have DataTime field called DateDeleted - which is null while user exists and is set to the proper value when user "is deleted".
I wonder if there is a way to introduce IsDeleted property for User entity so that
http://odata/service.svc/Users(1)/IsDeleted
will return true or false depending on whether DateDeleted is set or not
My research in google hasn't got any results and I am almost sure it is not possible to implement through odata. Am I right?
With the built in providers this is not possible on the WCF DS side of things. You might be able to somehow do this on the EF side (expose it as a property of the EF entity), but I'm not sure if that's possible.
On the WCF DS side, you would have to implement a custom provider in order to do this. Which may be quite a lot of work unfortunately. If you're interested see this for starters: http://blogs.msdn.com/b/alexj/archive/2010/01/07/data-service-providers-getting-started.aspx.
What Shawn refers to above is a method on the custom provider interface.
You can specify the value you want by implementing the method DataServiceQueryProvider.GetPropertyValue.
Please find the reference here:
http://msdn.microsoft.com/en-us/library/system.data.services.providers.idataservicequeryprovider.getpropertyvalue.aspx
The method takes two parameters, the entity object (a User instance) and the resource property (in this case "IsDeleted"). You can try to get the property value of "DataDeleted" from the entity object, and return the value of "IsDeleted" as you want.

Using repository pattern in ASP.NET MVC with a SQL Server DB; how to mock repository so its unit testable without breaking OOD

I've been learning the ASP.NET MVC framework using the Apress book "Pro ASP.NET MVC Framework" by Steven Sanderson. To that end I have been trying out a few things on a project that I am not that familar with but are things that I thing I should be doing, namely:
Using repository pattern to access my database and populate my domain/business objects.
Use an interface for the repository so it can be mocked in a test project.
Use inversion of control to create my controllers
I have an MVC web app, domain library, test library.
In my database my domain items have an Id represented as an int identity column. In my domain classes the setter is internal so only the repository can set it.
So my quandries/problems are:
Effectively all classes in the domain library can set the Id property, not good for OOP as they should be read-only.
In my test library I create a fake repository. However since it's a different assembly I can't set the Id properties on classes.
What do others do when using a database data store? I imagine that many use an integer Id as unique identifier in the database and would then need to set it the object but not by anything else.
Can't you set your objects' IDs during construction and make them read-only, rather than setting IDs through a setter method?
Or do you need to set the ID at other times. If that's the case, could you explain why?
EDIT:
Would it be possible to divorce the ID and the domain object? Does anything other than the repository need to know the ID?
Remove the ID field from your domain object, and have your repository implementations track object IDs using a private Dictionary. That way anyone can create instances of your domain objects, but they can't do silly things with the IDs.
That way, the IDs of the domain objects are whatever the repository implementation decides they are - they could be ints from a database, urls, or file names.
If someone creates a new domain object outside of the repository and say, tried to save it to your repository, you can look up the ID of the object and save it as appropriate. If the ID isn't there, you can either throw an exception to say you need to create the object using a repository method, or create a new ID for it.
Is there anything that would stop you from using this pattern?
you can use the InternalsVisibleTo attribute. It will allow the types from an assembly to be visible from the tests (provided they are in different assemblies).
Otherwise you can leave the property read-only for the external objects but in the same time have a constructor which has an ID parameter and sets the ID property. Then you can call that constructor.
Hope this helps.

Resources