コード例 #1
0
ファイル: BsonMapper.cs プロジェクト: S3NoSql/S3NoSql
        /// <summary>
        /// Register a property as a DbRefList - implement a custom Serialize/Deserialize actions to convert entity to $id, $ref only
        /// </summary>
        private static void RegisterDbRefList(BsonMapper mapper, MemberMapper member, string collectionName)
        {
            // get entity from list item type
            var entity = mapper.GetEntityMapper(member.UnderlyingType);

            member.Serialize = (list, m) =>
            {
                var result  = new BsonArray();
                var idField = entity.Id;

                foreach (var item in (IEnumerable)list)
                {
                    result.Add(new BsonDocument
                    {
                        { "$id", new BsonValue(idField.Getter(item)) },
                        { "$ref", collectionName }
                    });
                }

                return(result);
            };

            member.Deserialize = (bson, m) =>
            {
                var array = bson.AsArray;

                if (array.Count == 0)
                {
                    return(m.Deserialize(member.DataType, array));
                }

                var hasIdRef = array[0].AsDocument["$id"].IsNull;

                if (hasIdRef)
                {
                    // if no $id, deserialize as full (was loaded via Include)
                    return(m.Deserialize(member.DataType, array));
                }
                else
                {
                    // copy array changing $id to _id
                    var arr = new BsonArray();

                    foreach (var item in array)
                    {
                        arr.Add(new BsonDocument {
                            { "_id", item.AsDocument["$id"] }
                        });
                    }

                    return(m.Deserialize(member.DataType, arr));
                }
            };
        }
コード例 #2
0
ファイル: BsonMapper.cs プロジェクト: S3NoSql/S3NoSql
        /// <summary>
        /// Register a property mapper as DbRef to serialize/deserialize only document refenece _id
        /// </summary>
        public static void RegisterDbRef(BsonMapper mapper, MemberMapper member, string collectionName)
        {
            member.IsDbRef = true;

            if (member.IsList)
            {
                RegisterDbRefList(mapper, member, collectionName);
            }
            else
            {
                RegisterDbRefItem(mapper, member, collectionName);
            }
        }
コード例 #3
0
ファイル: BsonMapper.cs プロジェクト: S3NoSql/S3NoSql
        /// <summary>
        /// Use this method to override how your class can be, by defalut, mapped from entity to Bson document.
        /// Returns an EntityMapper from each requested Type
        /// </summary>
        protected virtual EntityMapper BuildEntityMapper(Type type)
        {
            var mapper = new EntityMapper
            {
                Members = new List <MemberMapper>(),
                ForType = type
            };

            var idAttr     = typeof(BsonIdAttribute);
            var ignoreAttr = typeof(BsonIgnoreAttribute);
            var fieldAttr  = typeof(BsonFieldAttribute);
            var indexAttr  = typeof(BsonIndexAttribute);
            var dbrefAttr  = typeof(BsonRefAttribute);

            foreach (var memberInfo in this.GetTypeMembers(type))
            {
                // checks [BsonIgnore]
                if (memberInfo.IsDefined(ignoreAttr, true))
                {
                    continue;
                }

                // checks field name conversion
                var name = this.ResolveFieldName(memberInfo.Name);

                // checks if is _id
                if (this.IsMemberId(type, memberInfo))
                {
                    name = "_id";
                }

                // check if property has [BsonField]
                var field = (BsonFieldAttribute)memberInfo.GetCustomAttributes(fieldAttr, false).FirstOrDefault();

                // check if property has [BsonField] with a custom field name
                if (field != null && field.Name != null)
                {
                    name = field.Name;
                }

                // test if field name is OK (avoid to check in all instances) - do not test internal classes, like DbRef
                if (BsonDocument.IsValidFieldName(name) == false)
                {
                    throw S3NoSqlException.InvalidFormat(memberInfo.Name, name);
                }

                // create getter/setter function
                var getter = Reflection.CreateGenericGetter(type, memberInfo);
                var setter = Reflection.CreateGenericSetter(type, memberInfo);

                // check if property has [BsonId] to get with was setted AutoId = true
                var autoId = (BsonIdAttribute)memberInfo.GetCustomAttributes(idAttr, false).FirstOrDefault();

                // checks if this proerty has [BsonIndex]
                var index = (BsonIndexAttribute)memberInfo.GetCustomAttributes(indexAttr, false).FirstOrDefault();

                // get data type
                var dataType = memberInfo is PropertyInfo ?
                               (memberInfo as PropertyInfo).PropertyType :
                               (memberInfo as FieldInfo).FieldType;

                // check if datatype is list/array
                var isList = Reflection.IsList(dataType);

                // create a property mapper
                var member = new MemberMapper
                {
                    AutoId         = autoId == null ? true : autoId.AutoId,
                    FieldName      = name,
                    MemberName     = memberInfo.Name,
                    DataType       = dataType,
                    IsUnique       = index == null ? false : index.Unique,
                    IsList         = isList,
                    UnderlyingType = isList ? Reflection.GetListItemType(dataType) : dataType,
                    Getter         = getter,
                    Setter         = setter
                };

                // check if property has [BsonRef]
                var dbRef = (BsonRefAttribute)memberInfo.GetCustomAttributes(dbrefAttr, false).FirstOrDefault();

                if (dbRef != null && memberInfo is PropertyInfo)
                {
                    BsonMapper.RegisterDbRef(this, member, dbRef.Collection);
                }

                // support callback to user modify member mapper
                if (this.ResolveMember != null)
                {
                    this.ResolveMember(type, memberInfo, member);
                }

                // test if has name and there is no duplicate field
                if (member.FieldName != null && mapper.Members.Any(x => x.FieldName == name) == false)
                {
                    mapper.Members.Add(member);
                }
            }

            return(mapper);
        }