예제 #1
0
        private object ObtainPrimaryKeyValue(Castle.ActiveRecord.Model model, CompositeNode node, String prefix, out KeyValuePair <string, IType> pkModel)
        {
            pkModel = ObtainPrimaryKey(model);

            var pkPropName = pkModel.Key;

            var idNode = node.GetChildNode(pkPropName);

            if (idNode == null)
            {
                return(null);
            }

            if (idNode != null && idNode.NodeType != NodeType.Leaf)
            {
                throw new BindingException("Expecting leaf node to contain id for ActiveRecord class. " +
                                           "Prefix: {0} PK Property Name: {1}", prefix, pkPropName);
            }

            var lNode = (LeafNode)idNode;

            if (lNode == null)
            {
                throw new BindingException("ARDataBinder autoload failed as element {0} " +
                                           "doesn't have a primary key {1} value", prefix, pkPropName);
            }

            bool conversionSuc;

            return(Converter.Convert(pkModel.Value.ReturnedClass, lNode.ValueType, lNode.Value, out conversionSuc));
        }
예제 #2
0
        private object LoadActiveRecord(Type type, object pk, ARFetchAttribute attr, Castle.ActiveRecord.Model model)
        {
            object instance = null;

            if (pk != null && !String.Empty.Equals(pk))
            {
                var pkModel = ObtainPrimaryKey(model);

                var pkType = pkModel.Value.ReturnedClass;

                bool conversionSucceeded;
                var  convertedPk = _converter.Convert(pkType, pk.GetType(), pk, out conversionSucceeded);

                if (!conversionSucceeded)
                {
                    throw new ActiveRecordException(string.Format("ARFetcher could not convert PK {0} to type {1}", pk, pkType));
                }

                if (string.IsNullOrEmpty(attr.Eager))
                {
                    // simple load
                    instance = attr.Required
                                ? AR.Find(type, convertedPk)
                                : AR.Peek(type, convertedPk);
                }
                else
                {
                    // load using eager fetching of lazy collections
                    var criteria = DetachedCriteria.For(type);
                    criteria.Add(Expression.Eq(pkModel.Key, convertedPk));
                    foreach (var associationToEagerFetch in attr.Eager.Split(','))
                    {
                        var clean = associationToEagerFetch.Trim();
                        if (clean.Length == 0)
                        {
                            continue;
                        }

                        criteria.SetFetchMode(clean, FetchMode.Eager);
                    }

                    var result = AR.Execute(type, s => criteria.GetExecutableCriteria(s).List());
                    if (result.Count > 0)
                    {
                        instance = result[0];
                    }
                }
            }

            if (instance == null && attr.Create)
            {
                instance = Activator.CreateInstance(type);
            }

            return(instance);
        }
예제 #3
0
        private static KeyValuePair <string, IType> ObtainPrimaryKey(Castle.ActiveRecord.Model model)
        {
            if (model.Metadata.IsInherited)
            {
                var parent = AR.Holder.GetModel(model.Type.BaseType);
                return(ObtainPrimaryKey(parent));
            }

            return(model.PrimaryKey);
        }
예제 #4
0
        protected bool IsBelongsToRef(Castle.ActiveRecord.Model arModel, string prefix)
        {
            if (arModel.BelongsTos.ContainsKey(prefix))
            {
                return(true);
            }

            if (arModel.Metadata.IsInherited)
            {
                var parentmodel = AR.Holder.GetModel(arModel.Type.BaseType);
                return(IsBelongsToRef(parentmodel, prefix));
            }

            return(false);
        }
예제 #5
0
        protected bool FindPropertyInHasMany(Castle.ActiveRecord.Model model, string propertyName,
                                             ref Type foundType, ref Castle.ActiveRecord.Model foundModel)
        {
            foreach (var hasManyModel in model.HasManys)
            {
                // Inverse=true relations will be ignored
                if (hasManyModel.Key == propertyName && !hasManyModel.Value.Persister.IsInverse)
                {
                    foundType  = hasManyModel.Value.Persister.ElementType.ReturnedClass;
                    foundModel = AR.Holder.GetModel(foundType);
                    return(true);
                }
            }

            if (model.Metadata.IsInherited)
            {
                var basemodel = AR.Holder.GetModel(model.Type.BaseType);
                return(FindPropertyInHasMany(basemodel, propertyName, ref foundType, ref foundModel));
            }

            return(false);
        }
예제 #6
0
        public virtual Model GetModel(Type type)
        {
            type = GetNonProxyType(type);

            return Type2SessFactory.ContainsKey(type)
                ? Type2Model.GetOrAdd(type, t => {
                    var sf = GetSessionFactory(t);
                    var model = new Model(sf, type);
                    return model;
                })
                : null;
        }
예제 #7
0
        protected override object BindSpecialObjectInstance(Type instanceType, string prefix, Node node,
                                                            out bool succeeded)
        {
            succeeded = false;

            var model = CurrentARModel;

            if (model == null)
            {
                return(null);
            }

            var container = CreateContainer(instanceType);

            Type targetType = null;

            Castle.ActiveRecord.Model targetModel = null;

            var found = FindPropertyInHasAndBelongsToMany(model, prefix, ref targetType, ref targetModel);

            if (!found)
            {
                found = FindPropertyInHasMany(model, prefix, ref targetType, ref targetModel);
            }

            if (found)
            {
                succeeded = true;

                ClearContainer(container);

                if (node.NodeType == NodeType.Indexed)
                {
                    var indexNode = (IndexedNode)node;

                    var collArray = Array.CreateInstance(targetType, indexNode.ChildrenCount);

                    collArray = (Array)InternalBindObject(collArray.GetType(), prefix, node);

                    foreach (var item in collArray)
                    {
                        AddToContainer(container, item);
                    }
                }
                else if (node.NodeType == NodeType.Leaf)
                {
                    var pkModel = targetModel.PrimaryKey;
                    var pkType  = pkModel.Value.ReturnedClass;

                    var leafNode = (LeafNode)node;

                    bool convSucceeded;

                    if (leafNode.IsArray)
                    {
                        // Multiples values found
                        foreach (var element in (Array)leafNode.Value)
                        {
                            var keyConverted = Converter.Convert(pkType, leafNode.ValueType.GetElementType(), element, out convSucceeded);

                            if (convSucceeded)
                            {
                                var item = FindByPrimaryKey(targetType, keyConverted);
                                if (item != null)
                                {
                                    AddToContainer(container, item);
                                }
                            }
                        }
                    }
                    else
                    {
                        // Single value found
                        var keyConverted = Converter.Convert(pkType, leafNode.ValueType.GetElementType(), leafNode.Value, out convSucceeded);

                        if (convSucceeded)
                        {
                            var item = FindByPrimaryKey(targetType, keyConverted);
                            AddToContainer(container, item);
                        }
                    }
                }
            }

            return(container);
        }