/// <summary>
        /// 指示实体的某个属性是通过DB自动生成。
        /// </summary>
        /// <param name="expression">表示实体属性的表达式(示例:a=>a.P )。</param>
        /// <returns></returns>
        public DapperMetadataBuilder <T> AutoGeneration(Expression <Func <T, Object> > expression)
        {
            Guard.ArgumentNotNull(expression, nameof(expression));

            Expression      visited = expression.Body;
            UnaryExpression unary   = visited as UnaryExpression;

            if (unary != null)
            {
                visited = unary.Operand;
            }

            MemberExpression mex = visited as MemberExpression;

            if (mex != null)
            {
                string name       = MappingStrategyParser.Parse(mex.Member.Name);
                var    foundField = _mapping.Fields.FirstOrDefault(k => k.Name.CaseInsensitiveEquals(name));
                if (foundField != null)
                {
                    foundField.AutoGeneration = true;
                }
            }
            else
            {
                throw new ArgumentException($@"{nameof(DapperMetadataBuilder<T>)}.{nameof(AutoGeneration)} 
                                                                        方法只接受单个属性表达式,例如 a=>a.Property。");
            }
            return(this);
        }
Beispiel #2
0
        /// <summary>
        /// 创建 <see cref="FieldPredicate"/> 类的新实例。
        /// </summary>
        /// <param name="fieldName">参与二元运算的字段名。</param>
        /// <param name="binaryOperation">二元运算操作符。</param>
        /// <param name="value">用于运算的值。</param>
        public FieldPredicate(string fieldName, BinaryOperation binaryOperation, object value)
        {
            Guard.ArgumentNullOrWhiteSpaceString(fieldName, nameof(fieldName));

            this.FieldName      = MappingStrategyParser.Parse(fieldName);
            this.Operation      = binaryOperation;
            this.OperationValue = value;
        }
Beispiel #3
0
        public DapperMetadata(Type entityType)
        {
            Guard.ArgumentNotNull(entityType, nameof(entityType));

            this.EntityType = entityType;
            this.Fields     = entityType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                              .Where(p => p.CanRead && p.CanWrite && IsFieldType(p.PropertyType))
                              .Select(p => new DapperFieldMetadata(p)).ToArray();
            this.TableName = MappingStrategyParser.Parse(entityType.Name);
        }
        /// <summary>
        /// 指定实体的键。
        /// </summary>
        /// <param name="expression">表示实体键的表达式(示例:a=>a.P ,当需要复合键时使用 a=>new { a.P1, a.P2 })。</param>
        /// <returns></returns>
        public DapperMetadataBuilder <T> HasKey(Expression <Func <T, Object> > expression)
        {
            Guard.ArgumentNotNull(expression, nameof(expression));

            foreach (var f in _mapping.Fields)
            {
                f.IsKey = false;
            }

            Expression      visited = expression.Body;
            UnaryExpression unary   = visited as UnaryExpression;

            if (unary != null)
            {
                visited = unary.Operand;
            }

            MemberExpression mex = visited as MemberExpression;

            if (mex != null)
            {
                string name     = MappingStrategyParser.Parse(mex.Member.Name);
                var    keyField = _mapping.Fields.FirstOrDefault(p => p.Name.CaseInsensitiveEquals(name));
                if (keyField == null)
                {
                    throw new ArgumentException($"{nameof(DapperMetadataBuilder<T>)}.{nameof(DapperMetadataBuilder<T>.HasKey)} 方法传入的属性表达式找不到属性 {keyField}。");
                }
                if (keyField.Ignore)
                {
                    throw new ArgumentException($"{nameof(DapperMetadataBuilder<T>)}.{nameof(DapperMetadataBuilder<T>.HasKey)} 不能指定一个已忽略的属性作为 Key 。");
                }
                keyField.IsKey = true;
                return(this);
            }

            NewExpression newExpression = visited as NewExpression;

            if (newExpression != null)
            {
                var propertyNames = newExpression.Members.Select(m => MappingStrategyParser.Parse(m.Name)).ToArray();
                var keyProperties = _mapping.Fields.Where(f => propertyNames.Any(p => p.CaseInsensitiveEquals(f.Name))).ToArray();
                if (!keyProperties.Any())
                {
                    throw new ArgumentException($"{nameof(DapperMetadataBuilder<T>)}.{nameof(DapperMetadataBuilder<T>.HasKey)} 初始化对象表达式中至少要指定一个属性。");
                }
                if (keyProperties.Any(k => k.Ignore))
                {
                    throw new ArgumentException($"{nameof(DapperMetadataBuilder<T>)}.{nameof(DapperMetadataBuilder<T>.HasKey)} 不能指定已忽略的属性作为 Key 。");
                }
                keyProperties.ForEach(f => f.IsKey = true);
                return(this);
            }

            throw new ArgumentException($"{nameof(HasKey)} 方法使用了不支持的表达式作为 {nameof(expression)} 参数。");
        }
        internal DapperFieldMetadata(PropertyInfo field, PropertyConvention convention)
        {
            this.Field = field;
            this.Name  = MappingStrategyParser.Parse(field.Name);
            var rule    = convention.ColumnRule;
            var valueOf = new Func <PropertyConvention.DbColumnRule, PropertyConvention.DbColumnRule, bool>((x, y) => (x & y) == y);

            AutoGeneration = valueOf(rule, PropertyConvention.DbColumnRule.AutoGeneration);
            IsKey          = valueOf(rule, PropertyConvention.DbColumnRule.Key);
            Ignore         = valueOf(rule, PropertyConvention.DbColumnRule.Ignore);
        }
        /// <summary>
        /// 生成 In 从句。
        /// </summary>
        /// <param name="fieldName">字段名称。</param>
        /// <param name="values">字段值的集合。</param>
        /// <param name="parameters">查询参数</param>
        /// <returns></returns>
        public string GenerateInClause <TEntity>(string fieldName, IEnumerable <Object> values, DynamicParameters parameters)
        {
            if (fieldName.IsNullOrWhiteSpace() || values.IsNullOrEmpty())
            {
                return(null);
            }
            string parameterName = $"p{parameters.ParameterNames.Count() + 1}";

            parameters.Add(parameterName, values);
            return($"{_runtime.DelimitIdentifier(typeof(TEntity), MappingStrategyParser.Parse(fieldName))} IN {_runtime.DelimitParameter(typeof(TEntity), parameterName)}");
        }
        /// <summary>
        /// 根据字段名和值生成 SET 子句(不包含 SET 字符)。
        /// </summary>
        /// <param name="fieldsAndValues">要生成 SET 子句的字段名和字段值。</param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public string GenerateSetSegments <TEntity>(IEnumerable <KeyValuePair <String, Object> > fieldsAndValues, DynamicParameters parameters)
        {
            Guard.ArgumentNotNull(fieldsAndValues, nameof(fieldsAndValues));

            List <String> setString = new List <String>();

            foreach (var kp in fieldsAndValues)
            {
                string parameterName = $"p{(parameters.ParameterNames.Count() + 1)}";
                parameters.Add($"{parameterName}", kp.Value);
                setString.Add($"{_runtime.DelimitIdentifier(typeof(TEntity), MappingStrategyParser.Parse(kp.Key))} = {_runtime.DelimitParameter(typeof(TEntity), parameterName)}");
            }
            return(setString.ToArrayString(", "));
        }
        /// <summary>
        /// 生成实体主键的  Where 从句(不包含 Where 字符)。
        /// </summary>
        /// <param name="entity">实体类型</param>
        /// <param name="parameters">参数</param>
        /// <returns></returns>
        public String GeneratePrimaryKeysWhereClause <TEntity>(TEntity entity, DynamicParameters parameters)
        {
            Guard.ArgumentNotNull(parameters, nameof(parameters));
            Guard.ArgumentNotNull(parameters, nameof(parameters));

            var           keys     = this._runtime.GetMetadata(typeof(TEntity)).Fields.Where(f => f.IsKey).ToArray();
            List <String> whereSet = new List <String>();

            foreach (var k in keys)
            {
                string parameterName = $"p{parameters.ParameterNames.Count() + 1}";
                whereSet.Add($"{_runtime.DelimitIdentifier(typeof(TEntity), MappingStrategyParser.Parse(k.Name))} = {_runtime.DelimitParameter(typeof(TEntity), parameterName)}");
                parameters.Add(parameterName, k.Field.GetValue(entity));
            }
            return(whereSet.ToArrayString(" AND "));
        }
Beispiel #9
0
        public DapperMetadata(Type entityType, TypeConvention typeConvention, ModelConvention modelConvention)
        {
            Guard.ArgumentNotNull(entityType, nameof(entityType));
            this.EntityType = entityType;

            var metadatas = from prop in entityType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                            where prop.CanRead && prop.CanWrite && IsFieldType(prop.PropertyType)
                            let convention = modelConvention.PropertyConventions.FirstOrDefault(x => x.Filter(prop))
                                             select(convention != null ? new DapperFieldMetadata(prop, convention) : new DapperFieldMetadata(prop));


            this.Fields    = metadatas.ToArray();
            this.TableName = MappingStrategyParser.Parse(entityType.Name);


            if (typeConvention.Filter(entityType))
            {
                this.DbReadingConnectionName = typeConvention.DbReadingConnectionName;
                this.DbWritingConnectionName = typeConvention.DbWritingConnectionName;
            }
        }
 internal DapperFieldMetadata(PropertyInfo field)
 {
     this.Field = field;
     this.Name  = MappingStrategyParser.Parse(field.Name);
 }
Beispiel #11
0
        /// <summary>
        /// 生成 Order By 子句。
        /// </summary>
        /// <param name="sortOptions">排序选项。</param>
        /// <returns></returns>
        public string GenerateOrderBy <TEntity>(SortOptions sortOptions)
        {
            Guard.ArgumentNotNull(sortOptions, nameof(sortOptions));

            string fields = sortOptions.GetFields().Select(f => _runtime.DelimitIdentifier(typeof(TEntity), MappingStrategyParser.Parse(f))).ToArrayString(", ");
            string sql    = $" ORDER BY {fields}";

            if (sortOptions.SortOrder == SortOrder.Descending)
            {
                sql = String.Concat(sql, " desc");
            }
            return(sql);
        }