Mirko Lugano Mirko Lugano - 2 months ago 18
Javascript Question

Breezejs automatic GUID parsing

I am using Breezejs in 'NoDB' mode, meaning I write my metadata by hand. When I create a Breeze query with OData parameters I add a filter by id, say

new breeze.Predicate('iD', datacontext.breeze.FilterQueryOp.Equals, myId)


The var myId is indeed a GUID value (though it's defined as a String), but in my DB and in both my server-side and client-side model it's a string (I can't change the DB structure). the property definition in my metadata model is

dataProperties: {
...
iD: { dataType: DataType.String },
...
}


(I know the property name looks weird, but I have to use this syntax since I have the breeze.NamingConvention.camelCase.setAsDefault() on my datacontext, and the property's name on the DB is ID uppercased)
When I execute the query I see that the corresponding oData filter option in the WebAPI url is like

$filter=ID eq guid'65BEB144-5C0C-4481-AC70-5E61FDAA840D'


which leads me to this server error: No coercion operator is defined between types 'System.Guid' and 'System.String'.
Is there a way to disable this automatic 'parsing' of GUIDs and leave them as strings?
I have temporarily solved this by removing the parsing directly inside breeze's source code so that my webAPI call would look like

$filter=ID eq '65BEB144-5C0C-4481-AC70-5E61FDAA840D'


but I don't like this solution and I would be glad if there was a better one, like parametrize this behaviour in some way. I didn't find anything about this on Breeze's official website.

Answer

Breeze uses its metadata to determine that datatype of each property in a query and then uses this information to generate the correct OData filter. So your metadata definition of ID as a string should be correct.

However, in order to perform this operation breeze needs to know the EntityType of your query. For example in the following query

var q = EntityQuery.from("Foo").where(....)

breeze needs to know the EntityType that "Foo" ( a resourceName) corresponds to. Once it has the entity type it can correctly format any filters for specific properties of this entityType. If breeze does not have 'EntityType', then it falls back to guessing about the datatype of each property. In your case, its guessing that the datatype is a 'Guid'

So the fix is to either tell the query directly about the EntityType that you are querying

var q = breeze.EntityQuery.from("Foo).where(....).toType(FoosEntityType);

or you can handle it more globally via via the MetadataStore.setEntityTypeForResourceName method.

breeze.MetadataStore.setEntityTypeForResourceName("Foo", FoosEntityType);
var q = breeze.EntityQuery.from("Foo).where(....); // your original query