Home
Help
Register
Log in

Search

 
   Active Threads  

You are here: Home > LLBLGen Pro > Custom Templates> Finding an entity's relations in LPT template
 

Pages: 1
Custom Templates
Finding an entity's relations in LPT template
Page:1/1 

  Print all messages in this thread  
Poster Message
ww
User



Location:

Joined on:
01-Oct-2004 22:58:25
Posted:
65 posts
# Posted on: 13-May-2011 19:16:40.  
I'm using LLBLGen v3. I have an LPT template written in C# in which I need to accomplish the following:

* Find a relation in the current entity, given its navigator name.
* Generate different code depending on the relation type (OneToMany,ManyToOne, OneToOne).

I can't figure out how to find the relation, given an EntityDefinition.

Please let me know what I'm missing...
  Top
daelmo
Support Team



Location:
Guatemala City
Joined on:
28-Nov-2005 23:35:24
Posted:
8071 posts
# Posted on: 13-May-2011 19:54:13.  
Try this:


Code:
// here project is your ProjectDefinition object
var relationships = project.GetAllRelationshipsForEntity(yourEntity, true);
var rel = relationships.Where(r=>r.StartEntityNavigator == "SomeValidatorName");

switch (rel.RelationshipType)
{
     case EntityRelationshipType.OneToOne:
     ...
     break;

     case EntityRelationshipType.OneToMany:
     ...
     break;

     ... etc
}


David Elizondo
LLBLGen'ing (articles and code snippets) | linkedin | twitter
 
Top
ww
User



Location:

Joined on:
01-Oct-2004 22:58:25
Posted:
65 posts
# Posted on: 13-May-2011 21:41:05.  
Perfect, thanks. I was looking at properties and methods on the EntityDefinition--I didn't think to look at the project methods.
  Top
sunielreddy
User



Location:
USA
Joined on:
29-Sep-2011 00:52:17
Posted:
26 posts
# Posted on: 14-Mar-2012 23:42:21.  
I need to convert the following v2.6 template code to v3 template code.

//automatic relations
    for (int i = 0; i < currentEntity.Relations.Count; i++)
    {
                    bool process = false;
            if (currentEntity.Relations[i].RelationType != EntityRelationType.ManyToMany)
            {
                process = currentEntity.Relations[i].StartEntityIsPkSide;
            }


            if (process) {
                switch (currentEntity.Relations[i].RelationType)
                {
                    case EntityRelationType.OneToMany:
                        __outputWriter.Write("        private {0}DTOCollection f{1};\r\n", currentEntity.Relations[i].RelationEndName, currentEntity.Relations[i].RelationEndName);
                        __outputWriter.Write("        public {0}DTOCollection {1} {{ get {{ return f{1}; }} set {{ f{1} = value; }} }}\r\n", currentEntity.Relations[i].RelationEndName, currentEntity.Relations[i].UtilizingPropertyName);
                        break;
                    case EntityRelationType.ManyToOne:
                    case EntityRelationType.OneToOne:
                        __outputWriter.Write("        private {0}DTO f{1};\r\n", currentEntity.Relations[i].RelationEndName, currentEntity.Relations[i].UtilizingPropertyName);
                        __outputWriter.Write("        public {0}DTO {1} {{ get {{ return f{1}; }} set {{ f{1} = value; }} }}\r\n", currentEntity.Relations[i].RelationEndName, currentEntity.Relations[i].UtilizingPropertyName);
                        break;
                }
            }
        }
    


and this is what i have so far and i am not sure if this is right


            var relationships = _executingGenerator.ProjectDefinition.GetAllRelationshipsForEntity(currentEntity, true);
            foreach (var rel in relationships)
            {
                 bool process = false;
                    if (relEdge.RelationshipType != EntityRelationshipType.ManyToMany)
                    {
                        if (rel is NormalRelationshipEdge)
                        {
                            NormalRelationshipEdge nEdge = (NormalRelationshipEdge)rel;
                            process = nEdge.StartEntityIsPkSide;
                        }

                    }
                    if (process)
                    {
                        if (rel is NormalRelationshipEdge)
                        {
                            NormalRelationshipEdge nEdge = (NormalRelationshipEdge)rel;
                            switch (nEdge.RelationshipType)
                            {
                                case EntityRelationshipType.OneToMany:
                                    __outputWriter.Write("        private {0}DTOCollection f{1};\r\n", relEdge.EndEntityNavigator, relEdge.UniqueAssociationName);
                                    __outputWriter.Write("        public {0}DTOCollection {1} {{ get {{ return f{1}; }} set {{ f{1} = value; }} }}\r\n", relEdge.EndEntityNavigator, relEdge.UniqueAssociationName);
                                    break;
                                case EntityRelationshipType.ManyToOne:
                                case EntityRelationshipType.OneToOne:
                                    __outputWriter.Write("        private {0}DTO f{1};\r\n", relEdge.EndEntityNavigator, relEdge.UniqueAssociationName);
                                    __outputWriter.Write("        public {0}DTO {1} {{ get {{ return f{1}; }} set {{ f{1} = value; }} }}\r\n", relEdge.EndEntityNavigator, relEdge.UniqueAssociationName);
                                    break;
                            }
                        }
                    }
                }
            

The problem i am having is the StartEntityIsPKSide is always false even if the current entity is the primary key table.

For example I have two table ui_audit_sch_ltrs_hdr and ui_audit_sch_ltrs_dtl and they have one to many relationship between them. But when i call the method GetAllRelationshipsForEntity for the current entity the relations I get is reverse of what I have in the database. So if i have one-to-many relationship the normalrelationship edge RelationType property value is ManyToOne.

I am attaching the quick watch window of the relations object from visual studio. If you see in the attached image the startvertex is uiauditschltrsdtl and endvertext is uiauditschltrshdr and i think it should be the otherway.

Thanks

Sunil Gaddam








Sunil  Top
sunielreddy
User



Location:
USA
Joined on:
29-Sep-2011 00:52:17
Posted:
26 posts
# Posted on: 14-Mar-2012 23:58:33. Goto attachments  
Forgot to add the attachment - Sorry
Sunil  Top
Walaa
Support Team



Location:

Joined on:
21-Aug-2005 16:03:48
Posted:
14484 posts
# Posted on: 15-Mar-2012 11:38:38.  
This was an issue in v.3.0 but should be fixed in v.3.1
Could you please use the latest release of v.3.1


  Top
sunielreddy
User



Location:
USA
Joined on:
29-Sep-2011 00:52:17
Posted:
26 posts
# Posted on: 15-Mar-2012 17:19:05. Goto attachments  
I downloaded the latest version v3.1 and i am still having the same issue. I am attaching an image with assembly version info of the core dlls.

Let me know what needs to be done to fix this issue.

Thanks

Sunil Gaddam
Sunil  Top
daelmo
Support Team



Location:
Guatemala City
Joined on:
28-Nov-2005 23:35:24
Posted:
8071 posts
# Posted on: 15-Mar-2012 21:48:31.  
I'm not sure whether or not this is a bug, I suspect that old v3.0 bug is something else. Let me explain from my experience: the edge may have any direction PK<->FK or FK<->PK, that depends on how the relationship was created, normally the relationships that results from reverse-engineer the DB result in m:1 edges where the start entity id FK side and the end entity is the PK side. If you create a new relationship from the designer and you create it from the PK entity, the start entity would be the PK side and the end entity would be the FK side. So the direction is not relevant in your decision on whether or not process de relationship. Your interest is to know whether the entity you are processing is the PK side of the relationship. Try this:
Code:
if (rel is NormalRelationshipEdge)
{
     NormalRelationshipEdge nEdge = (NormalRelationshipEdge)rel;
     process = (nr.EntityPkSide.Name == entity.Name);
}

Also take this into account in the rest of your code. You should use relEdge.NavigatorFkSide instead of relEdge.EndEntityNavigator, because it could be that the EndNavigator is the Pk side.


David Elizondo
LLBLGen'ing (articles and code snippets) | linkedin | twitter
 
Top
sunielreddy
User



Location:
USA
Joined on:
29-Sep-2011 00:52:17
Posted:
26 posts
# Posted on: 16-Mar-2012 01:08:50.  
In my template code I have a switch statement checking for relation type and if Llblgen always return the reverse of the actual relationship type in the database then I will have to change the code in my template.

How come v2.6 returns the correct relationship type ?

Also relEdge.NavigatorFkSide returns primary key entity name which is wrong it should be the fk entity name.


Thanks
Sunil  Top
Otis
LLBLGen Pro Team



Location:
The Hague, The Netherlands
Joined on:
17-Aug-2003 18:00:36
Posted:
37476 posts
# Posted on: 16-Mar-2012 11:25:12.  
I now see you missed an important thing Regular Smiley
In v2.6, for every relationship there were 2 objects. Say you have Customer 1:n Order. In v2.6, there were 2 objects: Customer 1:n Order and Order m:1 Customer. In v3 there's just 1 object. When using reverse engineering to build your model, all relationship objects are always created like fkside relationshiptype pkside, so in the example above: Order m:1 Customer.

This relationship object, Order (startentity) m:1 Customer (endentity), is the 'edge' in a non-directed graph between Customer and Order (from both sides, so Order -> Customer and Customer -> Order). For this relationship object, Order m:1 Customer, StartEntityIsPkSide is false, as Order is the FK side.

There are methods available for you to obtain the information you need (we use them in the entity framework, l2s and nhibernate templates), but I don't know for sure what you want to accomplish. They key is however that you step away from the idea that if you are obtaining the relationships for Order, you'll get a different object for Order m:1 Customer than when you are obtaining the relationships for Customer, in v3 you'll get the _same_ object: Order m:1 Customer.

The best way I think is to start with the GeneratorlUtils methods (a class in the GeneratorCore assembly, see core designer reference manual). It contains a method called GetAllRelationshipInfosForEntity, which will return a list of RelationshipInfo objects which contain information per relationship and a relationshipinfo object's properties are valid for the entity you passed in.

So if we call that method for 'Order', we'll get a RelationshipInfo object back for Order m:1 Customer, where 'Navigator' has the value 'Customer', and 'OppositeNavigator' has the value 'Orders'. If we call the same method for 'Customer', we'll get a RelationshipInfo object back for the _same_ relationship object Order m:1 Customer (as there's just 1!) where 'Navigator' is 'Orders' and 'OppositeNavigator' is 'Customer'. Please have a look at that method and also the EF templates for 'Entity', e.g. the Poco entity template which shows how this method can be used, line 325 and further.


Frans Bouma
LLBLGen Pro / ORM Profiler Lead Developer | Blog | Twitter
 
Top
sunielreddy
User



Location:
USA
Joined on:
29-Sep-2011 00:52:17
Posted:
26 posts
# Posted on: 22-Mar-2012 07:11:20.  
Thanks Otis for the detailed explanation. Entity framework template code was really helpful for me in upgrading my v2.6 templates.

One more question

How can I find out the sequence name and database field type. In v2.6 I was using IdentityValueSequenceName and MappedFieldDBTypeAsString properties on the entity field definition but in the newer version I didn't find these properties.

Thanks

Sunil Gaddam
Sunil  Top
sunielreddy
User



Location:
USA
Joined on:
29-Sep-2011 00:52:17
Posted:
26 posts
# Posted on: 22-Mar-2012 07:42:59.  
Otis - Ignore my previous question I found the answer in a different thread.

Thanks

Sunil


Sunil  Top
Pages: 1  


Powered by HnD ©2002-2007 Solutions Design
HnD uses LLBLGen Pro

Version: 2.1.12172008 Final.