/// <summary> /// 指定实体的某个属性值是通过DB自动生成。 /// </summary> /// <param name="expression">表示实体属性的表达式(示例:a=>a.P )。</param> /// <returns></returns> public DapperMetadataBuilder <T> SetAutoGeneration(Expression <Func <T, object> > expression) { Guard.ArgumentNotNull(expression, nameof(expression)); Expression visited = expression.Body; if (visited is UnaryExpression unary) { visited = unary.Operand; } if (visited is MemberExpression mex) { string name = MappingStrategyParser.Parse(mex.Member.Name); var foundField = _dapperMetadata.Fields.FirstOrDefault(k => k.Name.CaseInsensitiveEquals(name)); if (foundField != null) { foundField.AutoGeneration = true; } } else { throw new ArgumentException($@"{nameof(DapperMetadataBuilder<T>)}.{nameof(SetAutoGeneration)} 方法只接受单个属性表达式,例如 a=>a.Property。"); } return(this); }
/// <summary> /// 构造函数 /// </summary> public DapperMetadata(Type entityType) { EntityType = entityType; Fields = entityType.GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(p => p.CanRead && p.CanWrite && CheckFieldType(p.PropertyType)) .Select(p => new DapperFieldMetadata(p)).ToList(); 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> SetPrimaryKey(Expression <Func <T, object> > expression) { Guard.ArgumentNotNull(expression, nameof(expression)); foreach (var f in _dapperMetadata.Fields) { f.IsKey = false; } Expression visited = expression.Body; if (visited is UnaryExpression unary) { visited = unary.Operand; } if (visited is MemberExpression mex) { string name = MappingStrategyParser.Parse(mex.Member.Name); var keyField = _dapperMetadata.Fields.FirstOrDefault(p => p.Name.CaseInsensitiveEquals(name)); if (keyField == null) { throw new ArgumentException($"{nameof(DapperMetadataBuilder<T>)}.{nameof(SetPrimaryKey)} 方法传入的属性表达式找不到属性 {name}。"); } if (keyField.Ignore) { throw new ArgumentException($"{nameof(DapperMetadataBuilder<T>)}.{nameof(SetPrimaryKey)} 不能指定一个已忽略的属性作为 Key 。"); } keyField.IsKey = true; return(this); } if (visited is NewExpression newExpression) { var propertyNames = newExpression.Members.Select(m => MappingStrategyParser.Parse(m.Name)).ToArray(); var keyProperties = _dapperMetadata.Fields.Where(f => propertyNames.Any(p => p.CaseInsensitiveEquals(f.Name))).ToArray(); if (!keyProperties.Any()) { throw new ArgumentException($"{nameof(DapperMetadataBuilder<T>)}.{nameof(SetPrimaryKey)} 初始化对象表达式中至少要指定一个属性。"); } if (keyProperties.Any(k => k.Ignore)) { throw new ArgumentException($"{nameof(DapperMetadataBuilder<T>)}.{nameof(SetPrimaryKey)} 不能指定已忽略的属性作为 Key 。"); } keyProperties.ForEach(f => f.IsKey = true); return(this); } throw new ArgumentException($"{nameof(SetPrimaryKey)} 方法使用了不支持的表达式作为 {nameof(expression)} 参数。"); }
/// <summary> /// 构造函数 /// </summary> /// <param name="field">字段</param> /// <param name="convention">属性约定</param> internal DapperFieldMetadata(PropertyInfo field, PropertyConvention convention) { Field = field; Name = MappingStrategyParser.Parse(field.Name); var rule = convention.DbColumnRule; var valueOf = new Func <DbColumnRule, DbColumnRule, bool>((x, y) => (x & y) == y); AutoGeneration = valueOf(rule, DbColumnRule.AutoGeneration); IsKey = valueOf(rule, DbColumnRule.Key); Ignore = valueOf(rule, DbColumnRule.Ignore); }
/// <summary> /// 构造函数 /// </summary> /// <param name="entityType"></param> /// <param name="typeConvention"></param> /// <param name="modelConvention"></param> public DapperMetadata(Type entityType, TypeConvention typeConvention, ModelConvention modelConvention) { Guard.ArgumentNotNull(entityType, nameof(entityType)); EntityType = entityType; var metadatas = from prop in entityType.GetProperties(BindingFlags.Public | BindingFlags.Instance) where prop.CanRead && prop.CanWrite && CheckFieldType(prop.PropertyType) let convention = modelConvention.PropertyConventions.FirstOrDefault(x => x.Filter(prop)) select convention != null ? new DapperFieldMetadata(prop, convention) : new DapperFieldMetadata(prop); Fields = metadatas.ToList(); TableName = MappingStrategyParser.Parse(entityType.Name); if (typeConvention.Filter(entityType)) { ReadingConnectionName = typeConvention.DbReadingConnectionName; WritingConnectionName = typeConvention.DbWritingConnectionName; } }
/// <summary> /// 构造函数 /// </summary> /// <param name="field">字段</param> internal DapperFieldMetadata(PropertyInfo field) { Field = field; Name = MappingStrategyParser.Parse(field.Name); }