示例#1
0
        public RelationNode(FieldInfo relationFieldInfo, NDORelationAttribute attr, ClassNode parent)
        {
            this.parent    = parent;
            this.fieldType = relationFieldInfo.FieldType;
            Type            parentType   = relationFieldInfo.ReflectedType;
            NDOAssemblyName an           = new NDOAssemblyName(parentType.Assembly.FullName);
            string          assShortName = an.Name;

            this.isElement = !(relationFieldInfo.FieldType == typeof(IList) ||
                               relationFieldInfo.FieldType.GetInterface("IList") != null ||
                               GenericIListReflector.IsGenericIList(relationFieldInfo.FieldType));

            // dataType & declaringType always have
            // - a class/valutype prefix
            // - an [AssName] prefix
            this.dataType = new ReflectedType(relationFieldInfo.FieldType).ILName;
            if (relationFieldInfo.DeclaringType != relationFieldInfo.ReflectedType)
            {
                this.declaringType = new ReflectedType(relationFieldInfo.DeclaringType).ILName;
            }
            else
            {
                this.declaringType = null;
            }
            this.name = relationFieldInfo.Name;

            Type attrType = attr.GetType();

            this.relationName = attr.RelationName;
            this.relationInfo = attr.Info;
            Type relType;

            if (isElement)
            {
                relType = relationFieldInfo.FieldType;
            }
            else
            {
                if (attr.RelationType == null && relationFieldInfo.FieldType.IsGenericType)
                {
                    relType = relationFieldInfo.FieldType.GetGenericArguments()[0];
                }
                else
                {
                    relType = attr.RelationType;
                }

                if (relType == null)
                {
                    throw new Exception("Can't determine referenced type in relation " + parent.Name + "." + this.name + ". Provide a type parameter for the [NDORelation] attribute.");
                }
            }

            if (relType.IsGenericType && !relType.IsGenericTypeDefinition)
            {
                relType = relType.GetGenericTypeDefinition();
            }

            // Related Type hat kein "class " Prefix, hat [assName] nur bei fremden Assemblies.
            this.relatedType = new ReflectedType(relType, assShortName).ILNameWithoutPrefix;
            if (relType.IsGenericType)
            {
                this.relatedType = this.relatedType.Substring(0, this.relatedType.IndexOf('<'));
            }

            object[] attrs = relationFieldInfo.GetCustomAttributes(typeof(ForeignKeyColumnAttribute), true);
            if (attrs.Length > 0)
            {
                this.foreignKeyColumnAttributes = new ForeignKeyColumnAttribute[attrs.Length];
                attrs.CopyTo(this.foreignKeyColumnAttributes, 0);
            }
            attrs = relationFieldInfo.GetCustomAttributes(typeof(ChildForeignKeyColumnAttribute), true);
            if (attrs.Length > 0)
            {
                this.childForeignKeyColumnAttributes = new ChildForeignKeyColumnAttribute[attrs.Length];
                attrs.CopyTo(this.childForeignKeyColumnAttributes, 0);
            }
            attrs = relationFieldInfo.GetCustomAttributes(typeof(MappingTableAttribute), true);
            if (attrs.Length > 0)
            {
                MappingTableAttribute = (MappingTableAttribute)attrs[0];
            }
        }
示例#2
0
        private void AnalyzeFields()
        {
            IList relations = new ArrayList();
            var   fis       = this.classType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Where(fi => !fi.IsInitOnly);

            foreach (FieldInfo fi in fis)
            {
                string fname = fi.Name;
                if (fname.StartsWith("_ndo"))
                {
                    continue;
                }
                if (fi.FieldType.IsSubclassOf(typeof(System.Delegate)))
                {
                    continue;
                }

                object[] attributes = fi.GetCustomAttributes(false);
                bool     cont       = false;
                foreach (System.Attribute attr in attributes)
                {
                    if (attr is NDOTransientAttribute)
                    {
                        cont = true;
                        break;
                    }
                    if (attr is NDORelationAttribute)
                    {
                        this.relations.Add(new RelationNode(fi, (NDORelationAttribute)attr, this));
                        cont = true;
                        break;
                    }
                }
                if (cont)
                {
                    continue;
                }

                // Field type is persistent - assume relation with element multiplicity.
                if (typeof(IPersistenceCapable).IsAssignableFrom(fi.FieldType))
                {
                    NDORelationAttribute nra = new NDORelationAttribute(fi.FieldType, RelationInfo.Default);
                    this.relations.Add(new RelationNode(fi, nra, this));
                    continue;
                }

                // Field is a collection - assume that it is either a relation or a transient field.
                if (GenericIListReflector.IsGenericIList(fi.FieldType))
                {
                    if (typeof(IPersistenceCapable).IsAssignableFrom(fi.FieldType.GetGenericArguments()[0]))
                    {
                        NDORelationAttribute nra = new NDORelationAttribute(fi.FieldType.GetGenericArguments()[0], RelationInfo.Default);
                        this.relations.Add(new RelationNode(fi, nra, this));
                    }
                    else
                    {
                        Console.WriteLine("Warning: The field " + this.name + "." + fi.Name + " is a generic collection to a nonpersistent type. NDO assumes, that this field is transient.");
                    }
                    continue;
                }

                if (!fi.FieldType.IsGenericParameter && fi.FieldType.IsClass && fi.FieldType != typeof(string) && fi.FieldType != typeof(byte[]))
                {
                    this.embeddedTypes.Add(new EmbeddedTypeNode(fi));
                }
                else
                {
                    FieldNode fn = new FieldNode(fi);
                    this.fields.Add(fn);
                    Type ft = fi.FieldType;
                    if (ft.IsValueType && !ft.IsEnum && !StorableTypes.Contains(ft))
                    {
                        ValueTypes.Instance.Add(new ValueTypeNode(ft));
                    }
                }
            }

            // If there is more than one relation to the same target type
            // without relation name, assign a relation name automatically
            foreach (var group in this.relations.GroupBy(r => r.RelatedType))
            {
                if (group.Count() < 2)
                {
                    continue;
                }
                int countWithoutName = 0;
                foreach (var rel in group)
                {
                    if (string.IsNullOrEmpty(rel.RelationName))
                    {
                        if (countWithoutName > 0)
                        {
                            string relname = rel.Name;
                            if (relname[0] == '<')
                            {
                                int q = relname.IndexOf('>');
                                if (q == -1)
                                {
                                    q = relname.Length;
                                }
                                relname = relname.Substring(1, q - 1);
                            }
                            rel.RelationName = relname;
                        }
                        countWithoutName++;
                    }
                }
            }
        }