/// <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); }
/// <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; }
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 ")); }
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); }
/// <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); }