private static void CreateTablesLinkEnum(EntityDefinition entity, CodeTypeDeclaration entitySchemaDefClass)
        {
            if (!entity.InheritsBaseTables || entity.GetSourceFragments().Count() > 0)
            {
                var fullTables = entity.GetSourceFragments();

                CodeTypeDeclaration tablesEnum = new CodeTypeDeclaration("TablesLink")
                {
                    Attributes = MemberAttributes.Public,
                    IsClass    = false,
                    IsEnum     = true,
                    IsPartial  = false
                };

                if (entity.BaseEntity != null)
                {
                    tablesEnum.Attributes |= MemberAttributes.New;
                }

                int tableNum = 0;

                tablesEnum.Members.AddRange(fullTables.Select(tbl => new CodeMemberField
                {
                    InitExpression = new CodePrimitiveExpression(tableNum++),
                    Name           = WXMLCodeDomGeneratorNameHelper.GetSafeName(tbl.Identifier)
                }).ToArray());
                entitySchemaDefClass.Members.Add(tablesEnum);
            }
        }
        private void GetRelationMethods(string relationIdentifier, string propName)
        {
            if (Settings.UseTypeInProps)
            {
                string cln = new WXMLCodeDomGeneratorNameHelper(_settings).GetEntityClassName(_entity, false);
                //string dn = cln + ".Descriptor";

                Members.Add(Define.Method(MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static,
                                          typeof(RelationDescEx),
                                          (EntityUnion hostEntity) => "Get" + propName,
                                          Emit.@return((EntityUnion hostEntity) =>
                                                       new RelationDescEx(hostEntity, new M2MRelationDesc(
                                                                              new EntityUnion(CodeDom.TypeOf(cln)),
                                                                              relationIdentifier
                                                                              ))
                                                       )
                                          ));
            }
            else
            {
                //string cln = new WXMLCodeDomGeneratorNameHelper(_settings).GetEntityClassName(_entity, true);
                const string dn = "Descriptor";//cln + ".Descriptor";

                Members.Add(Define.Method(MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static,
                                          typeof(RelationDescEx),
                                          (EntityUnion hostEntity) => "Get" + propName,
                                          Emit.@return((EntityUnion hostEntity) =>
                                                       new RelationDescEx(hostEntity, new M2MRelationDesc(
                                                                              new EntityUnion(CodeDom.Field <string>(CodeDom.TypeRef_str(dn), "EntityName")),
                                                                              relationIdentifier
                                                                              ))
                                                       )
                                          ));
            }

            Members.Add(Define.Method(MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static,
                                      typeof(RelationDescEx),
                                      (EntityUnion hostEntity, EntityUnion joinEntity) => "Get" + propName,
                                      Emit.@return((EntityUnion hostEntity, EntityUnion joinEntity) =>
                                                   new RelationDescEx(hostEntity, new M2MRelationDesc(
                                                                          joinEntity,
                                                                          relationIdentifier
                                                                          ))
                                                   )
                                      ));
        }
Example #3
0
        private void ProcessOne2Many()
        {
            foreach (EntityDefinition e_ in Model.GetEntities())
            {
                EntityDefinition e = e_;

                foreach (EntityDefinition oe_ in
                         from k in Model.GetActiveEntities()
                         where /*k != e && */ !e.One2ManyRelations.Any(item =>
                                                                       !item.Disabled && item.Entity.Identifier == k.Identifier)
                         select k)
                {
                    EntityDefinition oe = oe_;
                    var entityProps     = oe.GetActiveProperties()
                                          .Where(item =>
                                                 item.PropertyType.IsEntityType &&
                                                 item.PropertyType.Entity.Identifier == e.Identifier)
                                          .Cast <EntityPropertyDefinition>();
                    int idx = 1;
                    foreach (EntityPropertyDefinition pd in entityProps)
                    {
                        int cnt = Model.GetActiveRelations().OfType <RelationDefinition>().Count(r =>
                                                                                                 (r.Left.Entity.Identifier == oe.Identifier && r.Right.Entity.Identifier == e.Identifier) ||
                                                                                                 (r.Left.Entity.Identifier == e.Identifier && r.Right.Entity.Identifier == oe.Identifier));

                        string accName = null; string prop = null;
                        if (cnt > 0 || entityProps.Count() > 1)
                        {
                            accName = WXMLCodeDomGeneratorNameHelper.GetMultipleForm(oe.Name + idx);
                            prop    = pd.Name;
                        }

                        e.AddEntityRelations(new EntityRelationDefinition()
                        {
                            Entity        = oe,
                            SourceEntity  = e,
                            AccessorName  = accName,
                            PropertyAlias = prop,
                        });
                        idx++;
                    }
                }
            }
        }
 public CodeEntityPropertyField(WXMLCodeDomGeneratorSettings settings, ScalarPropertyDefinition property)
 {
     Type       = property.PropertyType.ToCodeType(settings);
     Name       = new WXMLCodeDomGeneratorNameHelper(settings).GetPrivateMemberName(property.Name);
     Attributes = WXMLCodeDomGenerator.GetMemberAttribute(property.FieldAccessLevel);
 }
        private CodeCompileUnit GenerateModificationTracker(WXMLModel model, WXMLCodeDomGeneratorSettings setting)
        {
            var c = new CodeDomGenerator();

            string mtName = "LinqModificationTracker";

            var cls = c.AddNamespace(model.Namespace).AddClass(mtName);

            _ctxName = model.Namespace + "." + model.LinqSettings.ContextName;
            _mtName  = model.Namespace + "." + mtName;

            string conn = ConfigurationManager.ConnectionStrings["wms"].ConnectionString;

            cls.Implements(typeof(IModificationTracker))
            .AddEnum("ActionEnum")
            .AddFields(
                Define.StructField("Update"),
                Define.StructField("Insert"),
                Define.StructField("Delete")
                );

            cls.AddField("_changed", () => new List <object>());
            cls.AddField("_deleted", () => new List <object>());

            var tableType = new CodeTypeReference(typeof(System.Data.Linq.Table <>));

            tableType.TypeArguments.Add(new CodeTypeReference("T"));

            cls
            .AddMethod(MemberAttributes.Public | MemberAttributes.Final, (ParamArray <object> entities) => "Add",
                       Emit.stmt((List <object> _changed, object[] entities) => _changed.AddRange(entities)))
            .Implements(typeof(IModificationTracker))
            .AddMethod(MemberAttributes.Public | MemberAttributes.Final, (ParamArray <object> entities) => "Delete",
                       Emit.stmt((List <object> _deleted, object[] entities) => _deleted.AddRange(entities)))
            .Implements(typeof(IModificationTracker))
            .AddMethod(MemberAttributes.Public | MemberAttributes.Final, () => "AcceptModifications",
                       Emit.@using(new CodeTypeReference(_ctxName), "ctx", () => CodeDom.@new(_ctxName, conn),
                                   Emit.@foreach("entity", () => [email protected] <IEnumerable <object> >("_changed"),
                                                 Emit.stmt((object entity) => [email protected]("SyncEntity")(CodeDom.VarRef("ctx"), entity, false))
                                                 ),
                                   Emit.@foreach("entity", () => [email protected] <IEnumerable <object> >("_deleted"),
                                                 Emit.stmt((object entity) => [email protected]("SyncEntity")(CodeDom.VarRef("ctx"), entity, true))
                                                 ),
                                   Emit.stmt(() => CodeDom.VarRef("ctx").Call("SubmitChanges")),
                                   Emit.@foreach("entity", () => [email protected] <IEnumerable <object> >("_changed"),
                                                 Emit.stmt((object entity) => [email protected]("AcceptChanges")(entity))
                                                 ),
                                   Emit.stmt(() => [email protected] <List <object> >("_changed").Clear()),
                                   Emit.@foreach("entity", () => [email protected] <IEnumerable <object> >("_deleted"),
                                                 Emit.stmt((object entity) => [email protected]("AcceptChanges")(entity))
                                                 ),
                                   Emit.stmt(() => [email protected] <List <object> >("_deleted").Clear())
                                   )
                       ).Implements(typeof(IModificationTracker))
            .AddMethod(MemberAttributes.Private, () => "Dispose").Implements(typeof(IDisposable))
            .AddMethod(MemberAttributes.Private, (object entity) => "AcceptChanges",
                       Emit.declare("mi", (object entity) => entity.GetType().GetMethod("AcceptChanges")),
                       Emit.@if(() => CodeDom.VarRef("mi") != null,
                                Emit.stmt((MethodInfo mi, object entity) => mi.Invoke(entity, null))
                                )
                       )
            .AddMethod(MemberAttributes.Private, (DynType ctx, object entity, bool delete) => "SyncEntity" + ctx.SetType(_ctxName),
                       Emit.@foreach("mi", () => [email protected] <Type>("GetType")().GetMethods(BindingFlags.NonPublic | BindingFlags.Static),
                                     Emit.@if((bool delete, MethodInfo mi, object entity) =>
                                              ((delete && mi.Name == "_DelEntity") || (!delete && mi.Name == "_SyncEntity")) && mi.GetParameters().Count() == 2 && mi.GetParameters().Last().ParameterType == entity.GetType(),
                                              Emit.stmt((MethodInfo mi, object entity) => mi.Invoke(null, BindingFlags.Static, null, new object[] { CodeDom.VarRef("ctx"), entity }, null)),
                                              Emit.exitFor()
                                              )
                                     )
                       )
            .AddMethod(MemberAttributes.Private | MemberAttributes.Static, (DynType p, DynType action, DynType table) => "SyncEntity" + p.SetType("T") + action.SetType("ActionEnum") + table.SetType(tableType),
                       Emit.ifelse(() => CodeDom.VarRef("action") == CodeDom.Field(new CodeTypeReference("ActionEnum"), "Insert"),
                                   CodeDom.CombineStmts(Emit.stmt(() => CodeDom.VarRef("table").Call("InsertOnSubmit")(CodeDom.VarRef("p")))),
                                   Emit.ifelse(() => CodeDom.VarRef("action") == CodeDom.Field(new CodeTypeReference("ActionEnum"), "Delete"),
                                               CodeDom.CombineStmts(
                                                   Emit.stmt(() => CodeDom.VarRef("table").Call("Attach")(CodeDom.VarRef("p"))),
                                                   Emit.stmt(() => CodeDom.VarRef("table").Call("DeleteOnSubmit")(CodeDom.VarRef("p")))
                                                   ),
                                               Emit.stmt(() => CodeDom.VarRef("table").Call("Attach")(CodeDom.VarRef("p"), true))
                                               )
                                   )
                       ).Generic("T", typeof(object))
            ;

            WXMLCodeDomGeneratorNameHelper n = new WXMLCodeDomGeneratorNameHelper(setting);

            foreach (var entity in model.GetActiveEntities())
            {
                if (entity.GetPkProperties().Count() == 1)
                {
                    //string entityName = entity.Name;
                    string entityProp = WXMLCodeDomGeneratorNameHelper.GetMultipleForm(entity.Name);
                    string entityType = n.GetEntityClassName(entity, true);
                    string pkName     = entity.GetPkProperties().Single().Name;

                    cls.AddMethod(MemberAttributes.Static | MemberAttributes.Private,
                                  (DynType ctx, DynType p) => "_DelEntity" + ctx.SetType(_ctxName) + p.SetType(entityType),
                                  Emit.stmt(() => CodeDom.Call(null, "SyncEntity", new CodeTypeReference(entityType))(
                                                CodeDom.VarRef("p"),
                                                CodeDom.Field(new CodeTypeReference("ActionEnum"), "Delete"),
                                                CodeDom.VarRef("ctx").Property(entityProp))
                                            )
                                  )
                    .AddMethod(MemberAttributes.Static | MemberAttributes.Private,
                               (DynType ctx, DynType p) => "_SynEntity" + ctx.SetType(_ctxName) + p.SetType(entityType),
                               Emit.stmt(() => CodeDom.Call(null, "SyncEntity", new CodeTypeReference(entityType))(
                                             CodeDom.VarRef("p"),
                                             CodeDom.VarRef("p").Field <int>(pkName) == 0 ? CodeDom.Field(new CodeTypeReference("ActionEnum"), "Insert") : CodeDom.Field(new CodeTypeReference("ActionEnum"), "Update"),
                                             CodeDom.VarRef("ctx").Property(entityProp))
                                         )
                               )
                    ;
                }
            }

            string debug = c.GenerateCode(CodeDomGenerator.Language.CSharp);

            return(c.GetCompileUnit(CodeDomGenerator.Language.CSharp));
        }
        protected virtual void OnPupulateEntityRelations()
        {
            var relationDescType = new CodeTypeReference(typeof(RelationDescEx));

            foreach (var entityRelation in _entity.GetActiveOne2ManyRelations())
            {
                string accessorName = string.IsNullOrEmpty(entityRelation.AccessorName) ? WXMLCodeDomGeneratorNameHelper.GetMultipleForm(entityRelation.Entity.Name) : entityRelation.AccessorName;

                var staticProperty = new CodeMemberProperty
                {
                    Name       = accessorName + "Relation",
                    HasGet     = true,
                    HasSet     = false,
                    Attributes = MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static,
                    Type       = relationDescType
                };

                var entityTypeExpression     = Settings.UseTypeInProps ? WXMLCodeDomGeneratorHelper.GetEntityClassTypeReferenceExpression(_settings, entityRelation.Entity, entityRelation.Entity.Namespace != _entity.Namespace || _entity.ScopeNames().Any(item => item == entityRelation.Entity.Name)) : WXMLCodeDomGeneratorHelper.GetEntityNameReferenceExpression(_settings, entityRelation.Entity, entityRelation.Entity.Namespace != _entity.Namespace || _entity.ScopeNames().Any(item => item == entityRelation.Entity.Name));
                var selfEntityTypeExpression = Settings.UseTypeInProps ? WXMLCodeDomGeneratorHelper.GetEntityClassTypeReferenceExpression(_settings, _entity, false) : WXMLCodeDomGeneratorHelper.GetEntityNameReferenceExpression(_settings, _entity, false);

                staticProperty.GetStatements.Add(
                    new CodeMethodReturnStatement(
                        new CodeObjectCreateExpression(
                            relationDescType,
                            new CodeObjectCreateExpression(
                                typeof(EntityUnion),
                                selfEntityTypeExpression
                                ),
                            new CodeObjectCreateExpression(
                                typeof(RelationDesc),
                                new CodeObjectCreateExpression(
                                    new CodeTypeReference(typeof(EntityUnion)),
                                    entityTypeExpression
                                    ),
                                WXMLCodeDomGeneratorHelper.GetFieldNameReferenceExpression(_settings, entityRelation.Property, entityRelation.Entity.Namespace != _entity.Namespace || _entity.ScopeNames().Any(item => item == entityRelation.Entity.Name)),
                                new CodePrimitiveExpression(entityRelation.Name ?? "default")
                                )
                            )
                        )
                    );

                Members.Add(staticProperty);

                string cd = new WXMLCodeDomGeneratorNameHelper(_settings).GetEntityClassName(entityRelation.Property.Entity, entityRelation.Entity.Namespace != _entity.Namespace || _entity.ScopeNames().Any(item => item == entityRelation.Entity.Name)) + ".Properties";
                //string dn = new WXMLCodeDomGeneratorNameHelper(_settings).GetEntityClassName(entityRelation.Entity, true) + ".Descriptor";

                //CodeDom.Field<string>(CodeDom.TypeRef(dn), "EntityName")

                CodeExpression exp = CodeDom.GetExpression((EntityUnion hostEntity) =>
                                                           new RelationDescEx(hostEntity, new RelationDesc(
                                                                                  new EntityUnion(CodeDom.InjectExp <string>(0)),
                                                                                  CodeDom.Field <string>(CodeDom.TypeRef_str(cd), entityRelation.Property.PropertyAlias),
                                                                                  entityRelation.Name
                                                                                  )), entityTypeExpression);

                Members.Add(Define.Method(MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static,
                                          typeof(RelationDescEx),
                                          (EntityUnion hostEntity) => "Get" + staticProperty.Name,
                                          Emit.@return(exp)
                                          ));

                Members.Add(Define.Method(MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static,
                                          typeof(RelationDescEx),
                                          (EntityUnion hostEntity, EntityUnion joinEntity) => "Get" + staticProperty.Name,
                                          Emit.@return((EntityUnion hostEntity, EntityUnion joinEntity) =>
                                                       new RelationDescEx(hostEntity, new RelationDesc(
                                                                              joinEntity,
                                                                              CodeDom.Field <string>(CodeDom.TypeRef_str(cd), entityRelation.Property.PropertyAlias),
                                                                              entityRelation.Name
                                                                              ))
                                                       )
                                          ));

                var memberProperty = new CodeMemberProperty
                {
                    Name       = accessorName,
                    HasGet     = true,
                    HasSet     = false,
                    Attributes =
                        MemberAttributes.Public | MemberAttributes.Final,
                    Type = new CodeTypeReference(typeof(RelationCmd))
                };

                if (!string.IsNullOrEmpty(entityRelation.AccessorDescription))
                {
                    WXMLCodeDomGenerator.SetMemberDescription(memberProperty, entityRelation.AccessorDescription);
                }

                memberProperty.GetStatements.Add(
                    new CodeMethodReturnStatement(
                        new CodeMethodInvokeExpression(
                            new CodeThisReferenceExpression(),
                            "GetCmd",
                            new CodePropertyReferenceExpression(
                                new CodePropertyReferenceExpression(
                                    null, //WXMLCodeDomGeneratorHelper.GetEntityClassReferenceExpression(_settings, _entity, false),
                                    staticProperty.Name
                                    ),
                                "Rel"
                                )
                            )
                        )
                    );
                Members.Add(memberProperty);

                _gen.RaisePropertyCreated(null, this, memberProperty, null);
            }
        }
        protected virtual void OnPupulateM2MRelations()
        {
            var relationDescType = new CodeTypeReference(typeof(RelationDescEx));

            #region Relation
            foreach (var relation in _entity.GetM2MRelations(false))
            {
                if (relation.Left.Entity == relation.Right.Entity)
                {
                    throw new ArgumentException("To realize m2m relation on self use SelfRelation instead.");
                }

                LinkTarget link = relation.Left.Entity == _entity ? relation.Right : relation.Left;

                var accessorName  = link.AccessorName;
                var relatedEntity = link.Entity;

                if (string.IsNullOrEmpty(accessorName))
                {
                    // существуют похожие релейшены, но не имеющие имени акссесора
                    var lst =
                        link.Entity.GetM2MRelations(false).FindAll(
                            r =>
                            r.Left != link && r.Right != link &&
                            ((r.Left.Entity == _entity && string.IsNullOrEmpty(r.Right.AccessorName)) ||
                             (r.Right.Entity == _entity && string.IsNullOrEmpty(r.Left.AccessorName))));

                    if (lst.Count > 0)
                    {
                        throw new WXMLException(
                                  string.Format(
                                      "Существуют неоднозначные связи между '{0}' и '{1}'. конкретизируйте их через accessorName.",
                                      lst[0].Left.Entity.Name, lst[0].Right.Entity.Name));
                    }
                    accessorName = relatedEntity.Name;
                }
                accessorName = WXMLCodeDomGeneratorNameHelper.GetMultipleForm(accessorName);

                var entityTypeExpression = Settings.UseTypeInProps ? WXMLCodeDomGeneratorHelper.GetEntityClassTypeReferenceExpression(_settings, relatedEntity, relatedEntity.Namespace != _entity.Namespace) : WXMLCodeDomGeneratorHelper.GetEntityNameReferenceExpression(_settings, relatedEntity, relatedEntity.Namespace != _entity.Namespace);

                var desc = new CodeObjectCreateExpression(
                    new CodeTypeReference(typeof(M2MRelationDesc)),
                    entityTypeExpression);

                var staticProperty = new CodeMemberProperty
                {
                    Name       = accessorName + "Relation",
                    HasGet     = true,
                    HasSet     = false,
                    Attributes = MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static,
                    Type       = relationDescType
                };

                staticProperty.GetStatements.Add(new CodeMethodReturnStatement(
                                                     new CodeObjectCreateExpression(typeof(RelationDescEx),
                                                                                    new CodeObjectCreateExpression(typeof(EntityUnion),
                                                                                                                   WXMLCodeDomGeneratorHelper.GetEntityNameReferenceExpression(_settings, _entity, false)
                                                                                                                   ), desc)
                                                     ));

                desc.Parameters.Add(new CodePrimitiveExpression(relation.SourceFragment.Identifier));

                Members.Add(staticProperty);

                GetRelationMethods(relation.SourceFragment.Identifier, staticProperty.Name);

                var memberProperty = new CodeMemberProperty
                {
                    Name       = accessorName,
                    HasGet     = true,
                    HasSet     = false,
                    Attributes =
                        MemberAttributes.Public | MemberAttributes.Final,
                    Type = new CodeTypeReference(typeof(RelationCmd))
                };

                if (!string.IsNullOrEmpty(link.AccessorDescription))
                {
                    WXMLCodeDomGenerator.SetMemberDescription(memberProperty, link.AccessorDescription);
                }

                memberProperty.GetStatements.Add(
                    new CodeMethodReturnStatement(
                        new CodeMethodInvokeExpression(
                            new CodeThisReferenceExpression(),
                            "GetCmd",
                            new CodePropertyReferenceExpression(
                                new CodePropertyReferenceExpression(
                                    null, //WXMLCodeDomGeneratorHelper.GetEntityClassReferenceExpression(_settings, _entity, false),
                                    staticProperty.Name
                                    ),
                                "M2MRel"
                                )
                            )
                        )
                    );

                Members.Add(memberProperty);

                _gen.RaisePropertyCreated(null, this, memberProperty, null);
            }

            #endregion

            #region SelfRelation
            foreach (var relation in _entity.GetM2MSelfRelations(false))
            {
                var accessorName = relation.Direct.AccessorName;

                if (!string.IsNullOrEmpty(accessorName))
                {
                    var entityTypeExpression = Settings.UseTypeInProps ? WXMLCodeDomGeneratorHelper.GetEntityClassTypeReferenceExpression(_settings, _entity, false) : WXMLCodeDomGeneratorHelper.GetEntityNameReferenceExpression(_settings, _entity, false);

                    var desc = new CodeObjectCreateExpression(
                        new CodeTypeReference(typeof(M2MRelationDesc)),
                        entityTypeExpression);

                    accessorName = WXMLCodeDomGeneratorNameHelper.GetMultipleForm(accessorName);

                    var staticProperty = new CodeMemberProperty
                    {
                        Name       = accessorName + "Relation",
                        HasGet     = true,
                        HasSet     = false,
                        Attributes = MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static,
                        Type       = relationDescType
                    };

                    staticProperty.GetStatements.Add(new CodeMethodReturnStatement(
                                                         new CodeObjectCreateExpression(typeof(RelationDescEx),
                                                                                        new CodeObjectCreateExpression(typeof(EntityUnion),
                                                                                                                       WXMLCodeDomGeneratorHelper.GetEntityNameReferenceExpression(_settings, _entity, false)
                                                                                                                       ), desc)
                                                         ));

                    GetRelationMethods(relation.SourceFragment.Identifier, staticProperty.Name);

                    //desc.Parameters.Add(new CodePrimitiveExpression(relation.Direct.FieldName));
                    //desc.Parameters.Add(new CodeFieldReferenceExpression(
                    //    new CodeTypeReferenceExpression(typeof(M2MRelationDesc)),"DirKey")
                    //);
                    desc.Parameters.Add(new CodePrimitiveExpression(relation.SourceFragment.Identifier));

                    Members.Add(staticProperty);

                    var memberProperty = new CodeMemberProperty
                    {
                        Name       = accessorName,
                        HasGet     = true,
                        HasSet     = false,
                        Attributes =
                            MemberAttributes.Public | MemberAttributes.Final,
                        Type = new CodeTypeReference(typeof(RelationCmd))
                    };

                    if (!string.IsNullOrEmpty(relation.Direct.AccessorDescription))
                    {
                        WXMLCodeDomGenerator.SetMemberDescription(memberProperty, relation.Direct.AccessorDescription);
                    }

                    memberProperty.GetStatements.Add(
                        new CodeMethodReturnStatement(
                            new CodeMethodInvokeExpression(
                                new CodeThisReferenceExpression(),
                                "GetCmd",
                                new CodePropertyReferenceExpression(
                                    new CodePropertyReferenceExpression(
                                        null, //WXMLCodeDomGeneratorHelper.GetEntityClassReferenceExpression(_settings, _entity, false),
                                        staticProperty.Name
                                        ),
                                    "M2MRel"
                                    )
                                )
                            )
                        );

                    Members.Add(memberProperty);

                    _gen.RaisePropertyCreated(null, this, memberProperty, null);
                }

                accessorName = relation.Reverse.AccessorName;

                if (!string.IsNullOrEmpty(accessorName))
                {
                    var entityTypeExpression = WXMLCodeDomGeneratorHelper.GetEntityNameReferenceExpression(_settings, _entity, false);
                    var desc = new CodeObjectCreateExpression(
                        new CodeTypeReference(typeof(M2MRelationDesc)),
                        entityTypeExpression);

                    accessorName = WXMLCodeDomGeneratorNameHelper.GetMultipleForm(accessorName);

                    var staticProperty = new CodeMemberProperty
                    {
                        Name       = accessorName + "Relation",
                        HasGet     = true,
                        HasSet     = false,
                        Attributes = MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static,
                        Type       = relationDescType
                    };

                    staticProperty.GetStatements.Add(new CodeMethodReturnStatement(
                                                         new CodeObjectCreateExpression(typeof(RelationDescEx),
                                                                                        new CodeObjectCreateExpression(typeof(EntityUnion),
                                                                                                                       WXMLCodeDomGeneratorHelper.GetEntityNameReferenceExpression(_settings, _entity, false)
                                                                                                                       ), desc)
                                                         ));
                    //desc.Parameters.Add(new CodePrimitiveExpression(relation.Reverse.FieldName));
                    //desc.Parameters.Add(new CodeFieldReferenceExpression(
                    //    new CodeTypeReferenceExpression(typeof(M2MRelationDesc)),"RevKey")
                    //);
                    desc.Parameters.Add(new CodePrimitiveExpression(M2MRelationDesc.ReversePrefix + relation.SourceFragment.Identifier));

                    GetRelationMethods(relation.SourceFragment.Identifier, staticProperty.Name);

                    Members.Add(staticProperty);

                    var memberProperty = new CodeMemberProperty
                    {
                        Name       = accessorName,
                        HasGet     = true,
                        HasSet     = false,
                        Attributes =
                            MemberAttributes.Public | MemberAttributes.Final,
                        Type = new CodeTypeReference(typeof(RelationCmd))
                    };

                    if (!string.IsNullOrEmpty(relation.Reverse.AccessorDescription))
                    {
                        WXMLCodeDomGenerator.SetMemberDescription(memberProperty, relation.Reverse.AccessorDescription);
                    }

                    memberProperty.GetStatements.Add(
                        new CodeMethodReturnStatement(
                            new CodeMethodInvokeExpression(
                                new CodeThisReferenceExpression(),
                                "GetCmd",
                                new CodePropertyReferenceExpression(
                                    new CodePropertyReferenceExpression(
                                        null, //WXMLCodeDomGeneratorHelper.GetEntityClassReferenceExpression(_settings, _entity, false),
                                        staticProperty.Name
                                        ),
                                    "M2MRel"
                                    )
                                )
                            )
                        );

                    Members.Add(memberProperty);

                    _gen.RaisePropertyCreated(null, this, memberProperty, null);
                }
            }

            #endregion
        }