This project has moved. For the latest updates, please go here.

EF API: Execute Sparql Query for multiple types

Dec 21, 2013 at 8:09 AM
I need to execute a sparql query, and then have full control over which Entity Type gets bound to, given the current DataObject. I have a data model that is a mix between entity types and non-entity types. every node in my graph has an additional property called NodeType which is a reference to a metadata node containing information about that type. So in theory, I want to read that NodeType reference and use that to determine which model I bind my DataObject to.

Unfortunately I don't see a straightforward way to do that, mostly because I would end up having to rewrite some of the internal code as a workaround, and that would add more maintenance issues.

To put it another way, I want to execute a sparql query, and then for each DataObject result, I want to choose which type T to use BindDataObject<T> with. If this is something you would be open to adding, then perhaps a virtual method can be added to the BrightstarEntityContext which, given a pre-bound IDataObject, returns a System.Type object that is then used during the ExecuteQuery method for the binding.

The main ExecuteQuery method that uses this variant would have to return IEnumerable<BrightstarEntityObject>, but the individual members of that collection would be typed differently.

I understand this is won't work universally for all queries due to the fact that queries are not always constructed to include type data. For my purposes, I can always construct my queries to pull that information. I'm sure that anyone else who would use this type of function would need to (and in theory be able to) build that type of query as well. Since the methodology to resolve the System.Type will be a virtual method that exists in user-space, it will be up to the user to resolve that data and deal with any errors.

However, I don't think it's really obvious how to build an API call that provides this feature and at the same time make it user-friendly and obvious on how to use properly. Maybe it could be included if it is documented well. I think it is a potentially powerful feature that would be helpful to BrightstarDB.

One more issue is that, given an IDataObject, if I call GetPropertyValues on this object, will the triples already have been loaded into memory from the just-executed query, or will there be another pass to the underlying store to retrieve that information? In any case, efficiency isn't too big of an issue for starters (unless you have to later change the API to be more efficient)

I'd be interested in hearing your thoughts on this and any potential ideas. Sorry for the long post!
Dec 22, 2013 at 2:26 AM
Edited Dec 22, 2013 at 8:17 AM
I just discovered the memberInitExpression field of the sparqlQueryContext constructor. This might be exactly what I need here, so I'll give it a shot.

Edit: Looks like that part only works on non-entity types. I will come up with something but am open to suggestions on how to make it "less hacky".
Coordinator
Dec 22, 2013 at 11:37 AM
Did you know you can cast a returned entity to any other type of entity you want ? You can just call .Become<T> on the entity with whatever <T> you want. There isn't any documentation on this feature at the moment, which probably should be added. I would be interested to see if it meets your needs.

GetPropertyValues will load all the triples for the DataObject if they haven't already been loaded during the DataObject's lifetime and if your DataObject came from binding to a SPARQL query results set the DataObject will only be carrying its URI identifier, so yes there will be another trip back to the store. If there is a subest of properties you need then you can just build an anonymous type in the LINQ query so that you can pull the values out in one hit - it depends really on whether you then need to return a concrete instance of your entity back up the call stack.
Marked as answer by Nuzz604 on 12/23/2013 at 7:17 PM
Dec 24, 2013 at 2:17 AM
I think this will work for now. Thanks!