Complex property from another library causing template generation errors - How do I include a complex property like this?

58 views
Skip to first unread message

Steven Archibald

unread,
May 19, 2013, 1:01:07 PM5/19/13
to brightsta...@googlegroups.com
Lets say in one library of basic types for my application(BaseTypes), I have a simple class called "VehicleMeasure".
VehicleMeasure is composed of 4 properties, each with a get/set pair:
public int VehicleHeight {get; set;}
public int VehicleWidth {get; set;}
public int VehicleLength {get; set;}
public int VehicleWeight {get; set;}
 
In my "Entities" library, I have a brightstardb entity interface:
using BaseTypes;
 
[Entity]
public interface Vehicle
{
    string Id {get; }
    VehicleMeasure Measure {get; set;}
}
 
When I try to transform templates, I get an error :
Error 9 Running transformation: Invalid property: IVehicleType.Measure - the property type VehicleMeasure is not supported by Entity Framework.  
 
VehicleMeasure is NOT an entity. It is just a complex property that I want to include in one or two actual entities. A VehicleMeasure will never be persisted independently, and thus does not need an Id property.
 
How do I include a complex property like this?

Khalil Ahmed

unread,
May 20, 2013, 4:49:22 AM5/20/13
to brightsta...@googlegroups.com
Hi Steven,

Right now BrightstarDB only supports primitive types and entity classes - complex values are not supported. Its something we could look into adding support for in a later release as I can see it should be pretty straightforward to model a complex type that is composed of primitive types in RDF.

For the current implementation I think the best way to handle this is with a property added to the generated class. For example:

[Entity]
    public interface IVehicle
    {
        string Id { get; }
        int Height { get; set; }
        int Width { get; set; }
        int Length { get; set; }
        int Weight { get; set; }
    }

    public partial class Vehicle : IVehicle
    {
        public VehicleMeasure VehicleMeasure
        {
            get
            {
                return new VehicleMeasure
                {
                    VehicleHeight = this.Height,
                    VehicleWidth = this.Width,
                    VehicleLength = this.Length,
                    VehicleWeight = this.Weight
                };
            }
            set
            {
                this.Height = value.VehicleHeight;
                this.Width = value.VehicleWidth;
                this.Length = value.VehicleLength;
                this.Weight = value.VehicleWeight;
            }
        }
    }

So the primitive types are on the entity definition and the generated class is extended with a property that simply acts as a proxy that exposes your complex type. The only word of caution here is that you can't use the VehicleMeasure property in a LINQ expression, but you can use the property in code that you write either to create/update entities or to process entities that have been retrieved by a LINQ/SPARQL query.

Cheers

Kal


--
You received this message because you are subscribed to the Google Groups "BrightstarDB Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brightstardb-us...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Kal Ahmed
Director, Networked Planet Limited
e: kal....@networkedplanet.com
w: www.networkedplanet.com

Steven Archibald

unread,
Oct 6, 2013, 1:36:58 PM10/6/13
to brightsta...@googlegroups.com
So I gave up on BrightStarDB earlier because of this.

But wanted to try it again this weekend for another project. And am having a similar problem.
I want to have a list of claims for a user profile. A claim happens to be a type provided by Microsoft in the System.Security namespace.

This lack of ability to use a complex property (that is entirely reflectable) is a huge drawback! Am I going to have to  re-create every single type in a "brightstardb" acceptable manner? This seems to fly in the face of the whole "reusable code" paradigm of object oriented programming.

Khalil Ahmed

unread,
Oct 7, 2013, 2:53:38 AM10/7/13
to brightsta...@googlegroups.com
Hi Steven,

The problem with generically mapping complex types are pretty hard ones to get around:

1) Identity - BrightstarDB is based on RDF, and resources in RDF have strong identity. C# objects do not (generically) have strong identity. So you need to express (somehow) the way in which you create strong identity from the existing properties of the complex type or you need to extend the complex type to support managing a strong identifier.

2) Inverse properties - it isn't possible to determine by reflection which properties of two C# classes are true inverse relationships. You can't just do it by type because there may be examples where class A has two properties of type B and class B has only one of type A - which property of class A is that an inverse of ?

3) The whole notion of containment - doesn't really exist in a graph. RDF does have blank nodes (nominally unaddressable, but the issue about requiring a strong identity for management purposes still stands) and these can be (ab)used to create containment hierarchies, but its not a trivial problem for arbitrarily complex object graphs.

I don't position myself as the expert here - if you or anyone else has some suggestions or examples of how to address these problems please let me know, but I have yet to find an approach that would address all 3 of these issues without still requiring some sort of compile time configuration (whether it be in attributes or in some "fluent" configuration API a la ravendb).

There are ways around this that also encourage a cleaner, less dependent architecture - consider using Repository and Adapter patterns to abstract away the translation between B* entities and your system types.

Cheers

Kal


--
You received this message because you are subscribed to the Google Groups "BrightstarDB Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brightstardb-us...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Steven Archibald

unread,
Oct 7, 2013, 8:30:02 PM10/7/13
to brightsta...@googlegroups.com

Kahlil,

 

Thanks for responding. I guess this gets me back to my original question. And either there’s something about a Graph database that I’m completely mis-comprehending, or I’m not explaining my problem well enough. Let me try again.

 

Let’s take a fairly simple class, called Measure. Measure has 3 properties; length, width, height. Measure is a complex property that any Entity can contain, but Measure cannot exist independently – it will always be a property of something else. I want to use the class Measure as a property, because I want to ensure that all measures in all Entities use the same value types for length, width, and height, and no one can goof and use a different sort of value type.

 

In addition, I have some business rules about a Measure, e.g., the sum of all the measures cannot exceed 120 without throwing an error. This, for instance, would be a common rule in the package carriage industry, where a package submitted for carriage cannot exceed a total length when all the lengths of each dimension are added up.

 

Measure will never be an independent entity. It will always be contained within some other entity, and I must be able to contain it in more than one type of entity without having to re-code all the measure properties and business rules.

 

From a “real world” point of view, it makes no sense to me to have to force each instance of Measure in another entity, to have its own ID. It simply is NOT an independent entity.

 

Is there some mechanism in your product where I can use Measure as just an attribute of many different entities, without having to “re-code” it for each containing entity?

 

Regards,

Steven Archibald, President

Steven Archibald Consulting Corporation

e-mail: steven.a...@sa-consult.com

Architecture/ Design/ Development

 

"A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away."
Antoine de Saint-Exupery.

--
You received this message because you are subscribed to a topic in the Google Groups "BrightstarDB Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/brightstardb-users/vcLq-hbV2o0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to brightstardb-us...@googlegroups.com.

Khalil Ahmed

unread,
Oct 8, 2013, 4:01:37 AM10/8/13
to brightsta...@googlegroups.com
Hi Steven

Thanks for explaining the use case. I understand that this is something it would be genuinely useful to be able to do, but right now its not the way the mapping to objects currently works. I can think of some ways to maybe support this use case but it would by necessity be limited in scope because of the reasons I gave in my previous email. 

If the mapping layer in BrightstarDB don't know the ID of the complex value (because it has no ID) then an update to the value would need to either always rewrite all the triples involved (in your case at least three, one for each measure); or do some comparison on the property values to determine what changed and which triples to rewrite. It will, of course, get trickier when dealing with collections of complex values.

Right now there is no way to do this that would meet your requirements without coding the complex type up as a BrightstarDB entity. Perhaps it is something that could get added in a future version but its something that I need to think about more and scope out to a reasonable set of restrictions and behaviours.

Cheers

Kal

Steven Archibald

unread,
Nov 15, 2013, 6:32:11 PM11/15/13
to brightsta...@googlegroups.com
Khalil,

Ok. Assume instead of measure, I'm looking at a blood pressure measurement. Each measurement has three properties: diastolic pressure, systolic pressure, and pulse rate.
I'm taking the measurement every 4 seconds (15/minute). Over a 24 hour period I have 21,600 measurements. Over a year I have 7,884,000 blood pressure measurements. These are all tied to one patient/subscriber.

What sort of performance might I expect if I want to retrieve all 7,884,000 measurements for the year?
And would it make sense to have the "collection" of measurements be a property in my "patient" entity?
(I actually have a customer with a problem space like this [a little more complicated than I've described]... I can do it in SQL, but I'm not happy with it ...)

To unsubscribe from this group and stop receiving emails from it, send an email to brightstardb-users+unsub...@googlegroups.com.



 

--
Kal Ahmed
Director, Networked Planet Limited
e: kal....@networkedplanet.com
w: www.networkedplanet.com

--
You received this message because you are subscribed to a topic in the Google Groups "BrightstarDB Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/brightstardb-users/vcLq-hbV2o0/unsubscribe.

To unsubscribe from this group and all its topics, send an email to brightstardb-users+unsub...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "BrightstarDB Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brightstardb-users+unsub...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.
Reply all
Reply to author
Forward
0 new messages