Print Page | Close Window

Get entities and relations entire definition

Printed From: IdeaBlade
Category: DevForce
Forum Name: DevForce 2009
Forum Discription: For .NET 3.5
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=1369
Printed Date: 22-Sep-2025 at 4:22am


Topic: Get entities and relations entire definition
Posted By: ccancelado
Subject: Get entities and relations entire definition
Date Posted: 08-Jul-2009 at 1:53pm
Hi, I need to implement a tool to allow the user to select the Entities in a business model to generate a dynamic query.
I'm using the IdeaBlade.Util.ReflectionFns.GetTypesImplementing method to obtain the entities but I'm having problems to get the entities relations.
I'm trying to use EntityRelation.GetRelations(), but how can I change/select the Assembly to search the relations.

Any help will be appreciated. Thanks,
C. Cancelado



Replies:
Posted By: kimj
Date Posted: 10-Jul-2009 at 11:12am
You can get the relations using reflection also.  Something like this -
 
      Type er = ReflectionFns.GetTypesImplementing(typeof(EntityRelations), asm).First();
      List<FieldInfo> relations = er.GetFields().Where(f => f.FieldType == typeof(EntityRelation)).ToList();
(The Where clause is actually unnecessary since only EntityRelation fields are auto-generated into the EntityRelations class.)


Posted By: ccancelado
Date Posted: 19-Jul-2009 at 10:38am
Hi Kimj.

I try this code but it does not work. It returns an array with dimensions 0, I means it returns an empty array. Regading relations definitions, I think that it does not work because the relations are not implementing the EntityRelations interface.

Do you have another idea?

Please I need trly help on that.


Posted By: kimj
Date Posted: 20-Jul-2009 at 2:59pm
Maybe the assembly you are looking at does not have an EntityRelations class defined within it.  If you are iterating through a number of assemblies, not all of which may have this type, then don't use the First() method.  Once you find an EntityRelations type in an assembly, there will be 0 or more static fields of type EntityRelation.


Posted By: ccancelado
Date Posted: 27-Jul-2009 at 3:37am
Hi Kimj,

I'm sorry but it does not work. I'm using just an assembly each time, I'm not iterating through assemblies. I do not understand why the same code works for get the entities but not for get the relations.

I have really test all the posibilities but anything works. I just need to get the relations of an entity, I would like to get the information of an entity like IdeaBlade Object Mapper makes to construct the definitions. Is it possible?

Thanks,
C. Cancelado


Posted By: kimj
Date Posted: 27-Jul-2009 at 10:56am

You can post your code here if you like and we'll see what's going on. 

Also, take a look at the static methods on the EntityRelation class like GetEntityRelations(Type).


Posted By: ccancelado
Date Posted: 27-Jul-2009 at 11:16am
Off course, thanks.

I have a class EntitiesManager with the following code:

 public class EntitiesManager
    {
        public List<ReportDataObject> GetAvailableEntitiesList(BusinessModel aBusinessModel)
        {
            List<ReportDataObject> AvailableObjects = new List<ReportDataObject>();
            Type[] typesInModel = IdeaBlade.Util.ReflectionFns.GetTypesImplementing(typeof(Entity), new string[] {aBusinessModel.AssemblyName});
            Type[] er = IdeaBlade.Util.ReflectionFns.GetTypesImplementing(typeof(EntityRelations), new string[] { aBusinessModel.AssemblyName });
           
            //List<FieldInfo> relations = er.GetFields().Where(f => f.FieldType == typeof(EntityRelation)).ToList();
           
            foreach (Type TypeInModel in typesInModel)
            {
                if (TypeInModel.BaseType != typeof(Entity))
                {
                    EntityTypeInfo TheEntityTypeInfo = EntityTypeInfo.GetByType(TypeInModel);
                    RdbTableMappingInfo TheTableMappingInfo = (RdbTableMappingInfo)(TheEntityTypeInfo.PrototypeEntityTable.TableMappingInfo);
                    string tmpTableName = TheTableMappingInfo.SourceTableName;
                    ReportDataObject aReportDataObject = new ReportDataObject();
                    aReportDataObject.BusinessObjectName = TheEntityTypeInfo.EntityType.Name;
                    aReportDataObject.TableName = tmpTableName.Substring(tmpTableName.IndexOf(':')+1);
                    aReportDataObject.ObjectEntityType = TypeInModel;
                    AvailableObjects.Add(aReportDataObject);

                    System.Data.Common.DataColumnMappingCollection ColumnsMappings = TheTableMappingInfo.ColumnMappings;
                    List<ReportDataObjectField> AvailableObjectColumns = new List<ReportDataObjectField>();
                    List<EntityColumn> columns = new List<EntityColumn>();
                    foreach (EntityColumn column in EntityColumn.GetEntityColumns(TypeInModel))
                    {
                        if (!column.IsPrimaryKeyColumn)
                        {
                            string tmpColumnName = null;
                            for (int i = 0; i < ColumnsMappings.Count; i++)
                            {
                                if (column.ColumnName == ColumnsMappings.DataSetColumn)
                                {
                                    tmpColumnName = ColumnsMappings.SourceColumn;
                                }
                            }
                            ReportDataObjectField aReportDataObjectField = new ReportDataObjectField();
                            aReportDataObjectField.BusinessObjectFieldName = column.ColumnName;
                            aReportDataObjectField.TableFieldName = tmpColumnName;
                            aReportDataObjectField.ShowInReport = true;
                            aReportDataObjectField.FieldType = column.DataType;
                            aReportDataObjectField.ReportDataObject = aReportDataObject;
                            AvailableObjectColumns.Add(aReportDataObjectField);
                            columns.Add(column);
                        }
                    }
                    aReportDataObject.ReportDataObjectFields = AvailableObjectColumns;
                }
            }
            return AvailableObjects;
        }
    }

The GetAvailableEntities is called by a method that stores the result in a list and fills a DataSource in order to fill a Grid:
         private void LoadFieldLists()
        {
            SelectedBusinessModel = (BusinessModel)ModelsList.SelectedItem;
            if (SelectedBusinessModel != null)
            {
                availableTypesList = anEntitiesManager.GetAvailableEntitiesList(SelectedBusinessModel);
            }
            else
            {
                availableTypesList = new List<ABELSoft.AdHocReports.DynamicReports.ReportDataObject>();
            }
            AvailableTypesBS.DataSource = availableTypesList;
            SelectedTypesBS.DataSource = selectedTypesList;
            SimpleFormulaFieldsBS.DataSource = simpleFormulasList;
            ArrayFormulaFieldsBS.DataSource = groupingFormulasList;
        }

Tell me if you need more information. Thank you very much.
C. Cancelado


Posted By: kimj
Date Posted: 27-Jul-2009 at 12:17pm
OK, instead of using reflection use the static methods on EntityRelation.  First make sure that relations are loaded.
 
     // Do 1 time for the assembly.
      EntityRelation.InitializeEntityRelations(asm);
 
      // for each type, return the relations
      var rels = EntityRelation.GetEntityRelations(new Type[] { TypeInModel });


Posted By: ccancelado
Date Posted: 29-Jul-2009 at 1:58pm
Hi kimj,

It works, thank you very much. I have just a question, I have include the following code to get the relations:

                System.Reflection.Assembly asm = System.Reflection.Assembly.GetAssembly(aPrimReportObject.ObjectEntityType);
                EntityRelation.InitializeEntityRelations(asm);
                // getting all relations accordingly to current type
                List<EntityRelation> entityRelationList = new List<EntityRelation>(
                    EntityRelation.GetEntityRelations(new Type[] { aPrimReportObject.ObjectEntityType }));

After I get the columns of the relations:
                // processing each relation
                foreach (EntityRelation oneEntityRelation in entityRelationList)
                {
                        _PKColumns = oneEntityRelation.ParentColumns;
                        _FKColumns = oneEntityRelation.ChildColumns;
                }

As PKColumns and FKColumns are EntityColumns Arrays (EntityColumn[]), I would like to know how can I obtain the columns pair, I mean, if I have a relationship Parent.Id=Child.ParentId and Parent.Code=Child.PatientCode (this is just an example), ParentColumns will have two EntityColumns Id and Code and  ChildColumns will have two EntityColumns ParentId and ParentCode, ¿how can I know that the relation Id is with ParentId and Code is with ParentCode?

¿Relations have the same order in the array? ¿I can do the following?:
                 for (int i=0; i<_PKColumns.length(); i++)
                {
                        PKColum = _PKColumns;
                        FKColumn = _FKColumn;
                }

I have just one relation with two fields, allways when I run the code it looks like the columns are in order by I would like just to be sure.

Any help will be appreciated.

Thanks,
C. Cancelado


Posted By: ccancelado
Date Posted: 29-Jul-2009 at 2:01pm
I'm sorry. I have an error in the code posted in the previous post:

¿Columns have the same order in the two relations arrays? ¿I can do the following?:
                 for (int i=0; i<_PKColumns.length(); i++)
                {
                        PKColum = _PKColumns;
                        FKColumn = _FKColumn;
                }

I have just one relation with two fields, allways when I run the code it looks like the columns are in order by I would like just to be sure.

Any help will be appreciated.

Thanks,
C. Cancelado



Posted By: ccancelado
Date Posted: 29-Jul-2009 at 2:02pm
for (int i=0; i<_PKColumns.length(); i++)
                {
                        PKColum = _PKColumns;
                        FKColumn = _FKColumn;
                }


Posted By: ccancelado
Date Posted: 29-Jul-2009 at 2:05pm
I cannot include the square brackets. Well I hope you understand.


Posted By: kimj
Date Posted: 29-Jul-2009 at 3:43pm
Yes, the ParentColumns and ChildColumns on the EntitytRelation will be in the same order when multiple columns are involved.


Posted By: ccancelado
Date Posted: 29-Jul-2009 at 4:02pm
Thats great, so thank you very much for all your help.



Print Page | Close Window