RelatedEntities Methods

Posts   
 
    
Jessynoo avatar
Jessynoo
Support Team
Posts: 296
Joined: 19-Aug-2004
# Posted on: 21-Jan-2007 22:49:41   

Hi Frans,

here's a problem I'm having regularly, so I'm wondering if you made some plans about it.

It's about exploring a fetched arbitrary entity. I think there were quite a few posts about the need for Reflection to get access to the entity relations, I won't develop too much on that side though I think it's quite related.

Quickly, my opinion is that their should be a IRelationCollection property declared/implemented in the base entity classes and related factories/providers, associated with the currently generated Relations, just as the "Fields" property associates with the generated Field Properties.

Regardless, in order to explore an entity without relying to Reflection, one can use the 3 following methods:

GetDependingRelatedEntities GetDependentRelatedEntities GetMemberEntityCollections

they return objects of type List(of IEntity/IEntityCollection)

Now, the problem that I'm facing is that this does not give enough information about the relations/related properties

For instance, when performing a compared entity exploration (to set up an update from an imported entity), I did not find any easier way to correctly identify the members of those lists than by relying on the Xml Serialization of the respected parent entities to get the property names associated to the related entities (that may be an alternative to Reflection in my situation).

By the end, I'm thinking I had better coding the whole algorithm based on the serialized XML, which IMHO paradoxally exposes more/easier-to-access information about an arbitrary IEntity2 than the object itself.

Did you plan to add new properties / update existing to the entitybase classes in the incoming version?

For instance, if the functions mentioned above (or alternative functions to remain compatible) returned Dictionary(of String, IEntity/IEntityCollection) instead of lists, with the keys being the corresponding property/relation names, I think I could have coded without the need for the XML Serialized data.

Also, the Entity2Xml methods currently breaks with memory consumption for big entity trees, which makes my code even trickier. Do you have some news about the awaited XMLSerialization improvements?

Cheers

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 22-Jan-2007 12:06:01   

So basicly, you want to know the name "Orders" for the relation Customer-Order, for the CustomerEntity class, as "Orders" is the field mapped onto that relation ?

If so, could you explain to me in what sense you need this name exactly? (example). The information is currently not stored in the EntityRelation objects, obtained from the relations class for an entity. I could add that information, though it would bloat runtime-data a bit. If you could give me a use-case which justifies this addition, it would be great simple_smile

Frans Bouma | Lead developer LLBLGen Pro
Jessynoo avatar
Jessynoo
Support Team
Posts: 296
Joined: 19-Aug-2004
# Posted on: 22-Jan-2007 13:18:49   

Well, I would say that the property name is not really the important bit, it's just a matter of identifying the relation path associated to the inner entity property, which is what I'm looking for.

One might need that information for quite a few task as soon as one wants to explore the entity dynamically without prior knowledge on its type (IEntity2 is what I've got).

My current task consists in providing a sync mechanism so that entities can be imported from a development DB to the prod one.

The importing functions use the same PrefetchPath than the exporting ones in order to fetch potential matching existing entities: I can provide specific predicates to match the entities given their types.

I suppose I could do that step by step by browsing the concrete entity classes explicitely, but I need something more generic since there are quite a few types to import, with deep paths.

The general exploration can be done by using the inner entities properties such as GetDependingRelatedEntities. But then for a given entity of those, I only have its type to hand, which is not sufficient to do the mapping (several relations between 2 given entity types may conflict).

Other similar tasks in the past bringing the same issue were for instance developing generic web controls to expose predicates, to choose prefetch paths, to display entity trees etc....

IMHO, it's about the same as what you need to provide the DataAccessAdapter and corresponding DQE in order to be able to perform a query against an IEntity2: the DAA needs to browse the IEntityFields2 rather than the corresponding generated properties.

It does not need to browse the relations because they are provided in the buckets and prefetchpaths, but for everything related to building or identifying those relations in concrete entity or given their entity type, you face the same problem, which to my knowledge requires either using Reflection or relying on the serialized XML.

Actually, the EntityDefinition class from the application core namespace does expose such a "Relations" property, and it's definitely useful at designer or generation time, I reckon that missing that information at runtime is a limitation.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 24-Jan-2007 11:50:48   

Jessynoo wrote:

Well, I would say that the property name is not really the important bit, it's just a matter of identifying the relation path associated to the inner entity property, which is what I'm looking for.

Ok, though that's hard to do, as identifying a relation between two entities is really a matter of specifying all fields involved in the relation. This is a bit cumbersome if you want to lookup a relation.

One might need that information for quite a few task as soon as one wants to explore the entity dynamically without prior knowledge on its type (IEntity2 is what I've got).

True, you mean the meta-data available to you in the llblgen pro project?

My current task consists in providing a sync mechanism so that entities can be imported from a development DB to the prod one.

The importing functions use the same PrefetchPath than the exporting ones in order to fetch potential matching existing entities: I can provide specific predicates to match the entities given their types.

I suppose I could do that step by step by browsing the concrete entity classes explicitely, but I need something more generic since there are quite a few types to import, with deep paths.

The general exploration can be done by using the inner entities properties such as GetDependingRelatedEntities. But then for a given entity of those, I only have its type to hand, which is not sufficient to do the mapping (several relations between 2 given entity types may conflict).

I indeed think these collections aren't the ones you should be looking at, although at the same time, what information exactly do you need?

I mean: say you have an IEntity2, do you need: IEntity2.Relations, which returns a List<EntityRelation> instance? and every EntityRelation object in there contains the property in the IEntity2 instance, so with another method, like: IEntity2.GetRelatedData(name) you get the collection or entity which is related based on the EntityRelation specified?

IMHO, it's about the same as what you need to provide the DataAccessAdapter and corresponding DQE in order to be able to perform a query against an IEntity2: the DAA needs to browse the IEntityFields2 rather than the corresponding generated properties.

It does not need to browse the relations because they are provided in the buckets and prefetchpaths, but for everything related to building or identifying those relations in concrete entity or given their entity type, you face the same problem, which to my knowledge requires either using Reflection or relying on the serialized XML.

The XML deserializer uses reflection indeed, as it needs to do that, because custom properties can be present in the xml as well.

Actually, the EntityDefinition class from the application core namespace does expose such a "Relations" property, and it's definitely useful at designer or generation time, I reckon that missing that information at runtime is a limitation.

Ok, one way to overcome this now is to generate a class which builds up a hashtable or set of hashtables with data for each entity. You could do that with a template and the class could be used at runtime to obtain the information you need.

The reluctance I have at the moment for adding this information is that it adds code-bloat without a reason for the framework. It currently uses hardcoded code to quickly process data instead of having to look up relations and other info in a static repository which is filled from a mapping file.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 30-Jan-2007 10:22:51   

Btw, I think I need this info (which field of which entity is mapped onto a relation) for some v2.1 features so I'll add this to the v2.1 codebase, which would make it easier for you to traverse the relations I think, still I think a specialized template which create the class with the data you really need in the format you can use best is more appropriate.

Frans Bouma | Lead developer LLBLGen Pro
Jessynoo avatar
Jessynoo
Support Team
Posts: 296
Joined: 19-Aug-2004
# Posted on: 30-Jan-2007 23:33:45   

Hi Frans,

thx for that. Sorry I don't have much time those days to feed that discussion, but that seems good news anyway.

IEntity2.Relations, which returns a List<EntityRelation> instance? and every EntityRelation object in there contains the property in the IEntity2 instance, so with another method, like: IEntity2.GetRelatedData(name) you get the collection or entity which is related based on the EntityRelation specified

That would be ideal but anything making things easier is welcome. Anyway, I ended up making a Reflection Helper serving the missing data, so there's no urge for us anymore.

Cheers

jwright
User
Posts: 2
Joined: 02-Oct-2007
# Posted on: 06-May-2008 22:19:41   

I know this thread has been idle for a while, but I was hoping take it a bit further.

I understand how to get related entities/collections from an IEntity (I'm in self-servicing), but is there a way to match those entities/collections with the name of the relation?

So basicly, you want to know the name "Orders" for the relation Customer-Order, for the CustomerEntity class, as "Orders" is the field mapped onto that relation ?

This is exactly what I'm looking for.

If so, could you explain to me in what sense you need this name exactly? (example).

Here's my example... I'm serializing entities to JSON by looking at the Fields property on an IEntity interface, but I'd like to also serialize related entities by passing a depth to the first entity. So


   customer.ToJSon(0);

would serialize the customer.


   customer.ToJSon(1);

would serialize the customer and orders. The kicker is that the orders collection would need to be named "Orders".

I know this kind of serialization can be done in an entirely different way with templates (with attributes on the properties to serialize), but I'd really rather not do templates for such a minor thing.

I'm not looking for code, just a little direction would be great. If it isn't possible, then that's cool too... I just thought I'd ask.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 07-May-2008 10:26:32   

In v2.5, it's possible to get all relations for an entity. So just call 'entity.GetAllRelations' and you'll get all relations back for the entity. Every IEntityRelation now has a field, which is the name of the field mapped onto that relation, e.g. 'Orders': IEntityRelation.MappedFieldName'.

You can also get all related data with names: entity.GetRelatedData(). THis returns a dictionary, key is the fieldname mappedonto the relation (e.g. 'Orders') and value is the object representing either the collection or the related entity, or null if nothing was loaded.

Frans Bouma | Lead developer LLBLGen Pro