コード例 #1
0
        /// <summary>
        /// Returns a generated array of <see cref="DbParameter"/>s
        /// that should be passed in with the command.
        /// </summary>
        /// <returns></returns>
        protected virtual DbParameter[] CreateParameters()
        {
            // add insert/update values
            var ret = new List <DbParameter>();

            foreach (var colmap_kvp in ModelMap.FieldMappings)
            {
                string fld = colmap_kvp.Key;
                DataModelColumnAttribute colmap = colmap_kvp.Value;
                DbParameter param = null;
                switch (StatementCommand)
                {
                case SqlStatement.INSERT:
                    if (string.IsNullOrEmpty(colmap.InsertParam))
                    {
                        continue;
                    }
                    if (colmap.IncludeOnInsert ||
                        colmap.ReturnAsOutputOnInsert)
                    {
                        param = Provider.DbFactory.CreateParameter();
                        param.ParameterName = !colmap.InsertParam.StartsWith("@")
                                                      ? "@" + colmap.InsertParam
                                                      : colmap.InsertParam;
                        if (colmap.ReturnAsOutputOnInsert)
                        {
                            param.Direction = ParameterDirection.Output;
                        }
                    }
                    break;

                case SqlStatement.UPDATE:
                    if (string.IsNullOrEmpty(colmap.UpdateParam))
                    {
                        continue;
                    }
                    bool add = true;
                    if (!CommandBuilder.SetAllValues)
                    {
                        add = DataModel.ModifiedProperties.Contains(fld);
                    }
                    if (add)
                    {
                        param = Provider.DbFactory.CreateParameter();
                        param.ParameterName = !colmap.UpdateParam.StartsWith("@")
                                                      ? "@" + colmap.UpdateParam
                                                      : colmap.UpdateParam;
                    }
                    break;
                }
                if (param != null && ret.Find(p => p.ParameterName == param.ParameterName) == null)
                {
                    if (param is SqlParameter)
                    {
                        ((SqlParameter)param).SqlDbType = colmap.SqlDbType;
                    }
                    else
                    {
                        param.DbType = colmap.DbType;
                    }
                    if (colmap.ColumnSize.HasValue)
                    {
                        param.Value = colmap.ColumnSize.Value;
                    }
                    else if (colmap.DataType == typeof(string))
                    {
                        param.Size = (DataModel[fld] ?? string.Empty).ToString().Length;
                    }
                    if (param.Direction == ParameterDirection.Input ||
                        param.Direction == ParameterDirection.InputOutput)
                    {
                        param.IsNullable = colmap.IsNullable;
                        param.Value      = DataModel[fld] ?? DBNull.Value;
                    }
                    ret.Add(param);
                }
            }

            foreach (var foreignMapping_kvp in ModelMap.ForeignModelMappings)
            {
                ForeignDataModelAttribute foreignMapping = foreignMapping_kvp.Value;
                if (foreignMapping.TargetMemberType.IsOrInherits(typeof(IEnumerable)))
                {
                    continue;
                }
                switch (StatementCommand)
                {
                case SqlStatement.INSERT:
                    var fieldValue = DataModel.ColumnMappedValue[foreignMapping.LocalColumn];
                    var paramName  = "@" + foreignMapping.LocalColumn;
                    if (ret.Find(p => p.ParameterName == paramName) == null)
                    {
                        if (ret.Find(p => p.ParameterName == paramName) != null)
                        {
                            continue;
                        }
                        var param = Provider.DbFactory.CreateParameter();
                        param.ParameterName = paramName;
                        if (param is SqlParameter)
                        {
                            ((SqlParameter)param).SqlDbType = foreignMapping.LocalColumnSqlDbType;
                        }
                        else
                        {
                            param.DbType = foreignMapping.LocalColumnDbType;
                        }
                        if (foreignMapping.LocalColumnSize.HasValue)
                        {
                            param.Value = foreignMapping.LocalColumnSize.Value;
                        }
                        else if (foreignMapping.TargetMemberType == typeof(string))
                        {
                            param.Size = (fieldValue ?? string.Empty).ToString().Length;
                        }
                        if (param.Direction == ParameterDirection.Input ||
                            param.Direction == ParameterDirection.InputOutput)
                        {
                            param.IsNullable = foreignMapping.LocalColumnIsNullable;
                            param.Value      = fieldValue ?? DBNull.Value;
                        }
                        ret.Add(param);
                    }
                    break;
                }
            }

            // add query conditions
            if (Query != null)
            {
                foreach (DataModelQueryCondition <TModel> cond in Query.Conditions)
                {
                    DataModelColumnAttribute fm = cond.FieldMap;
                    if (fm == null)
                    {
                        switch (cond.FindFieldMappingBy)
                        {
                        case FieldMappingKeyType.ClrMember:
                            fm = ModelMap[cond.EvalSubject];
                            break;

                        case FieldMappingKeyType.DbColumn:
                            fm = ModelMap.GetFieldMappingByDbColumnName(cond.EvalSubject);
                            break;
                        }
                    }
                    string paramName = string.Empty;
                    if (fm != null)
                    {
                        switch (StatementCommand)
                        {
                        case SqlStatement.SELECT:
                            if (string.IsNullOrEmpty(fm.SelectParam))
                            {
                                continue;
                            }
                            paramName = fm.SelectParam;
                            break;

                        case SqlStatement.INSERT:
                            if (string.IsNullOrEmpty(fm.InsertParam))
                            {
                                continue;
                            }
                            paramName = fm.InsertParam;
                            break;

                        case SqlStatement.UPDATE:
                            if (string.IsNullOrEmpty(fm.UpdateParam))
                            {
                                continue;
                            }
                            paramName = fm.UpdateParam;
                            break;

                        case SqlStatement.DELETE:
                            if (string.IsNullOrEmpty(fm.DeleteParam))
                            {
                                continue;
                            }
                            paramName = fm.DeleteParam;
                            break;
                        }
                        if (ret.Find(p => p.ParameterName == paramName) == null)
                        {
                            if (UsesSproc && cond.CompareOp != Compare.Equal)
                            {
                                throw new InvalidOperationException(
                                          "Cannot produce an ad hoc WHERE clause with a SQL Stored Procedure.");
                            }
                            DbParameter param = Provider.DbFactory.CreateParameter();
                            param.ParameterName = !paramName.StartsWith("@")
                                                      ? "@" + paramName
                                                      : paramName;
                            if (param is SqlParameter)
                            {
                                ((SqlParameter)param).SqlDbType = fm.SqlDbType;
                            }
                            else
                            {
                                param.DbType = fm.DbType;
                            }
                            if (fm.ColumnSize.HasValue)
                            {
                                param.Value = fm.ColumnSize.Value;
                            }
                            else if (fm.DataType == typeof(string))
                            {
                                fm.ColumnSize =
                                    (cond.CompareValue ?? string.Empty).ToString().Length;
                            }
                            param.IsNullable = fm.IsNullable;
                            param.Value      = cond.CompareValue ?? DBNull.Value;
                            ret.Add(param);
                        }
                    }
                    else
                    {
                        if (cond.CompareValue != null)
                        {
                            paramName = "@" + cond.EvalSubject;
                            if (ret.Find(p => p.ParameterName == paramName) == null)
                            {
                                DbParameter param = Provider.DbFactory.CreateParameter();
                                param.ParameterName = paramName;
                                if (param is SqlParameter)
                                {
                                    ((SqlParameter)param).SqlDbType
                                        = DbTypeConverter.ToSqlDbType(cond.CompareValue);
                                }
                                else
                                {
                                    param.DbType = DbTypeConverter.ToDbType(cond.CompareValue);
                                }
                                if (cond.CompareValue is string)
                                {
                                    param.Size = ((string)cond.CompareValue).Length;
                                }
                                param.IsNullable = true;
                                param.Value      = cond.CompareValue;
                                ret.Add(param);
                            }
                        }
                    }
                }
            }
            return(ret.ToArray());
        }
コード例 #2
0
ファイル: DataProviderBase.cs プロジェクト: stimpy77/gemli
        /// <summary>
        /// When implemented, loads the full object graph for the first
        /// <see cref="DataModel"/> that is returned from the specified
        /// <paramref name="query"/>, within the specified database
        /// <paramref name="transactionContext"/>.
        /// </summary>
        /// <param name="query"></param>
        /// <param name="transactionContext"></param>
        /// <param name="depth"></param>
        /// <param name="loadedModels">
        /// Used for keeping recursive loading from resulting
        /// in infinite loops. Evaluate each loaded item from
        /// a database result set against this collection; if
        /// there is a match, use the collection item,
        /// otherwise use the database loaded item, deep-load
        /// it, and add it to this collection.
        /// </param>
        /// <returns></returns>
        public virtual TModel DeepLoadModel <TModel>(
            DataModelQuery <TModel> query, int?depth, DbTransaction transactionContext,
            List <DataModel> loadedModels
            ) where TModel : DataModel
        {
            TModel e = LoadModel(query, transactionContext);

            if (e == null)
            {
                return(e);
            }
            if (loadedModels == null)
            {
                loadedModels = new List <DataModel>();
            }
            if (loadedModels.Contains(e))
            {
                return((TModel)loadedModels[loadedModels.IndexOf(e)]);
            }
            foreach (DataModel previouslyLoadedModel in loadedModels)
            {
                if (query.GetType().IsGenericType)
                {
                    Type qt = query.GetType().GetGenericArguments()[0];
                    if (previouslyLoadedModel.GetType().IsOrInherits(qt) &&
                        previouslyLoadedModel.Equals(e) &&
                        previouslyLoadedModel is TModel)
                    {
                        return((TModel)previouslyLoadedModel);
                    }
                }
            }
            if (!loadedModels.Contains(e))
            {
                loadedModels.Add(e);
            }
            foreach (var fe_kvp in e.EntityMappings.ForeignModelMappings)
            {
                if (depth == null || depth > 0)
                {
                    ForeignDataModelAttribute fe = fe_kvp.Value;
                    Type targetEntityType        = fe.TargetMemberType;
                    while (targetEntityType.IsGenericType &&
                           targetEntityType.IsOrInherits(typeof(IEnumerable)))
                    {
                        targetEntityType = targetEntityType.GetGenericArguments().Last();
                    }
                    if (!targetEntityType.IsDataModel())
                    {
                        targetEntityType = typeof(DataModel <>).MakeGenericType(targetEntityType);
                    }
                    Type subQueryType = typeof(DataModelQuery <>).MakeGenericType(targetEntityType);

                    Relationship relationship = fe.Relationship;
                    if (relationship == Relationship.ManyToMany &&
                        string.IsNullOrEmpty(fe.MappingTable))
                    {
                        relationship = Relationship.OneToMany;
                    }
                    switch (relationship)
                    {
                    case Relationship.OneToOne:
                    case Relationship.ManyToOne:
                        IDataModelQuery subQuery = ((IDataModelQuery)Activator.CreateInstance(subQueryType))
                                                   .WhereColumn[fe.RelatedTableColumn].IsEqualTo(
                            e.ColumnMappedValue[fe.LocalColumn]);

                        DataModel e2 = DeepLoadModel(targetEntityType, subQuery,
                                                     depth == null ? null : depth - 1,
                                                     transactionContext, loadedModels);
                        object e2o = e2;
                        if (!fe.TargetMemberType.IsDataModel())
                        {
                            e2o = (e2).Entity;
                        }
                        if (fe.TargetMember.MemberType == MemberTypes.Field)
                        {
                            ((FieldInfo)fe.TargetMember).SetValue(e.Entity, e2o);
                        }
                        else if (fe.TargetMember.MemberType == MemberTypes.Property)
                        {
                            ((PropertyInfo)fe.TargetMember).SetValue(e.Entity, e2o, new object[] {});
                        }
                        break;

                    case Relationship.OneToMany:
                        IDataModelQuery subQuery2 = ((IDataModelQuery)Activator.CreateInstance(subQueryType))
                                                    .WhereColumn[fe.RelatedTableColumn].IsEqualTo(
                            e.ColumnMappedValue[fe.LocalColumn]);

                        IDataModelCollection e2c = DeepLoadModels(targetEntityType, subQuery2, depth,
                                                                  transactionContext, loadedModels);
                        object e2ct = Activator.CreateInstance(fe.TargetMemberType);
                        if (e2ct is IList)
                        {
                            bool de = fe.TargetMemberType.IsGenericType &&
                                      fe.TargetMemberType.GetGenericArguments().Last().IsDataModel();
                            foreach (object e2cx in e2c)
                            {
                                if (de)
                                {
                                    ((IList)e2ct).Add(e2cx);
                                }
                                else
                                {
                                    object e2cx2 = ((DataModel)e2cx).Entity;
                                    ((IList)e2ct).Add(e2cx2);
                                }
                            }
                        }
                        else
                        {
                            e2ct = ((IList)e2c)[0];
                        }
                        if (fe.TargetMember.MemberType == MemberTypes.Field)
                        {
                            ((FieldInfo)fe.TargetMember).SetValue(e.Entity, e2ct);
                        }
                        else if (fe.TargetMember.MemberType == MemberTypes.Property)
                        {
                            ((PropertyInfo)fe.TargetMember).SetValue(e.Entity, e2ct, new object[] {});
                        }
                        break;

                    case Relationship.ManyToMany:
                        if (!fe.TargetMemberType.IsOrInherits(typeof(IList)))
                        {
                            throw new InvalidCastException(
                                      "Cannot apply ManyToMany binding to a non-IList property.");
                        }
                        Type tleft       = fe.DeclaringType;
                        Type tleftEntity = tleft;
                        while (tleftEntity.IsDataModelWrapper(true))
                        {
                            if (tleftEntity.BaseType != (typeof(DataModel <>)).BaseType)
                            {
                                tleftEntity = tleftEntity.BaseType;
                            }
                            else
                            {
                                tleftEntity = tleftEntity.GetGenericArguments()[0];
                            }
                        }
                        Type tright = (fe.TargetMemberType.IsGenericType &&
                                       !fe.TargetMemberType.IsDataModel() &&
                                       fe.TargetMemberType.IsOrInherits(typeof(IList)))
                                              ? fe.TargetMemberType.GetGenericArguments()[0]
                                              :
                                      fe.TargetMemberType;
                        Type trightEntity = tright;
                        if (!tright.IsDataModel())
                        {
                            tright = typeof(DataModel <>).MakeGenericType(tright);
                        }
                        Type mapType = typeof(DataModelMap.RuntimeMappingTable <,>)
                                       .MakeGenericType(
                            // left side of mapping table
                            fe.TargetMember.DeclaringType,
                            // right side
                            tright);
                        var mapObj = (DataModel)Activator.CreateInstance(mapType);
                        mapObj.EntityMappings.TableMapping.Schema = fe.MappingTableSchema ??
                                                                    ProviderDefaults.DefaultSchema;
                        mapObj.EntityMappings.TableMapping.Table = fe.MappingTable ??
                                                                   (string.Compare(trightEntity.Name,
                                                                                   tleftEntity.Name) == -1
                                                                            ? trightEntity.Name +
                                                                    tleftEntity.Name
                                                                            : tleftEntity.Name +
                                                                    trightEntity.Name);
                        DataModelColumnAttribute mapLeftCol = mapObj.EntityMappings.FieldMappings["LeftColumn"];
                        mapLeftCol.ColumnName = fe.LocalColumn;
                        mapLeftCol.DbType     = e.EntityMappings
                                                .GetFieldMappingByDbColumnName(fe.LocalColumn).DbType;
                        mapLeftCol.TargetMemberType = e.EntityMappings
                                                      .GetFieldMappingByDbColumnName(fe.LocalColumn).TargetMemberType;

                        Type mapQueryType = typeof(DataModelQuery <>).MakeGenericType(new[] { mapType });
                        var  mapQuery     = (IDataModelQuery)Activator.CreateInstance(mapQueryType);
                        mapQuery.WhereColumn[fe.LocalColumn].IsEqualTo(
                            e.ColumnMappedValue[fe.LocalColumn]);


                        IDataModelCollection mapdes = LoadModels(mapType, mapQuery, transactionContext);

                        var mappedDEs = new DataModelCollection <DataModel>();
                        foreach (DataModel de in mapdes)     // de is a MappingTable<L,R>
                        {
                            var mappedDEQuery = (IDataModelQuery)
                                                Activator.CreateInstance(typeof(DataModelQuery <>)
                                                                         .MakeGenericType(targetEntityType));
                            mappedDEQuery.WhereColumn[fe.RelatedTableColumn]
                            .IsEqualTo(de.ColumnMappedValue[fe.RelatedTableColumn]);

                            DataModel mappedDE = DeepLoadModel(targetEntityType, mappedDEQuery,
                                                               depth == null ? null : depth - 1,
                                                               transactionContext, loadedModels);

                            if (mappedDE != null)
                            {
                                mappedDEs.Add(mappedDE);
                            }
                        }

                        Type mmtargtype = fe.TargetMemberType;
                        var  mmtargcol  = (IList)Activator.CreateInstance(fe.TargetMemberType);
                        Type mapdeType  = null;
                        foreach (DataModel mapde in mappedDEs)
                        {
                            if (mapdeType == null)
                            {
                                mapdeType = mapde.GetType();
                            }
                            object deinst = mapde;
                            if (mmtargtype.IsGenericType &&
                                !mmtargtype.GetGenericArguments()[0].IsDataModel())
                            {
                                deinst = mapde.Entity;
                            }
                            mmtargcol.Add(deinst);
                        }
                        if (fe.TargetMember is FieldInfo)
                        {
                            ((FieldInfo)fe.TargetMember).SetValue(e, mmtargcol);
                        }
                        else if (fe.TargetMember is PropertyInfo)
                        {
                            ((PropertyInfo)fe.TargetMember).SetValue(
                                e.Entity, mmtargcol, new object[] {});
                        }
                        break;
                    }
                }
            }
            foreach (var field_kvp in e.EntityMappings.FieldMappings)
            {
                DataModelColumnAttribute field = field_kvp.Value;
                if (field.IsForeignKey &&
                    field.ForeignKeyMapping.AssignToMember != null)
                {
                    LoadMember(e, field, field_kvp.Key, transactionContext, loadedModels);
                }
            }
            return(e);
        }