void Init() { Type t = this.Type; var members = t.GetMembers(BindingFlags.Public | BindingFlags.Instance); Dictionary <MemberInfo, MRMTuple> mappingMemberMappers = new Dictionary <MemberInfo, MRMTuple>(); Dictionary <MemberInfo, Lazy <MemberValueSetter> > memberSetters = new Dictionary <MemberInfo, Lazy <MemberValueSetter> >(); foreach (var member in members) { if (!member.HasPublicSetter()) { continue; } //只支持公共属性和字段 Type memberType = member.GetMemberType(); memberSetters.Add(member, new Lazy <MemberValueSetter>(() => { MemberValueSetter valueSetter = MemberValueSetterContainer.GetMemberValueSetter(member); return(valueSetter); }, LazyThreadSafetyMode.ExecutionAndPublication)); Infrastructure.MappingType mappingType; if (MappingTypeSystem.IsMappingType(memberType, out mappingType)) { MRMTuple mrmTuple = MRMHelper.CreateMRMTuple(member, mappingType); mappingMemberMappers.Add(member, mrmTuple); } } this._mappingMemberMappers = PublicHelper.Clone(mappingMemberMappers); this._memberSetters = PublicHelper.Clone(memberSetters); }
void ConfigureNavigationProperty() { PropertyInfo[] properties = this.EntityType.Type.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(a => a.GetSetMethod() != null && a.GetGetMethod() != null).ToArray(); foreach (PropertyInfo property in properties) { if (MappingTypeSystem.IsMappingType(property.PropertyType)) { continue; } NavigationAttribute navigationAttribute = property.GetCustomAttribute <NavigationAttribute>(); if (navigationAttribute == null) { continue; } if (this.IsSupportedCollectionType(property.PropertyType)) { this.EntityType.CollectionProperties.Add(new CollectionProperty(property)); continue; } ComplexProperty complexProperty = new ComplexProperty(property); complexProperty.ForeignKey = navigationAttribute.ForeignKey; this.EntityType.ComplexProperties.Add(complexProperty); } }
protected override IMappingObjectExpression VisitMemberInit(MemberInitExpression exp) { IMappingObjectExpression result = this.Visit(exp.NewExpression); foreach (MemberBinding binding in exp.Bindings) { if (binding.BindingType != MemberBindingType.Assignment) { throw new NotSupportedException(); } MemberAssignment memberAssignment = (MemberAssignment)binding; MemberInfo member = memberAssignment.Member; Type memberType = member.GetMemberType(); //是数据库映射类型 if (MappingTypeSystem.IsMappingType(memberType)) { DbExpression dbExpression = this.ResolveExpression(memberAssignment.Expression); result.AddMappingMemberExpression(member, dbExpression); } else { //对于非数据库映射类型,只支持 NewExpression 和 MemberInitExpression IMappingObjectExpression subResult = this.Visit(memberAssignment.Expression); result.AddComplexMemberExpression(member, subResult); } } return(result); }
void Init() { Type t = this.Type; var members = t.GetMembers(BindingFlags.Public | BindingFlags.Instance); Dictionary <MemberInfo, IMRM> mappingMemberMappers = new Dictionary <MemberInfo, IMRM>(); Dictionary <MemberInfo, Action <object, object> > complexMemberSetters = new Dictionary <MemberInfo, Action <object, object> >(); foreach (var member in members) { Type memberType = null; PropertyInfo prop = null; FieldInfo field = null; if ((prop = member as PropertyInfo) != null) { if (prop.GetSetMethod() == null) { continue;//对于没有公共的 setter 直接跳过 } memberType = prop.PropertyType; } else if ((field = member as FieldInfo) != null) { memberType = field.FieldType; } else { continue;//只支持公共属性和字段 } MappingTypeInfo mappingTypeInfo; if (MappingTypeSystem.IsMappingType(memberType, out mappingTypeInfo)) { IMRM mrm = MRMHelper.CreateMRM(member, mappingTypeInfo); mappingMemberMappers.Add(member, mrm); } else { if (prop != null) { Action <object, object> valueSetter = DelegateGenerator.CreateValueSetter(prop); complexMemberSetters.Add(member, valueSetter); } else if (field != null) { Action <object, object> valueSetter = DelegateGenerator.CreateValueSetter(field); complexMemberSetters.Add(member, valueSetter); } else { continue; } continue; } } this._mappingMemberMappers = Utils.Clone(mappingMemberMappers); this._complexMemberSetters = Utils.Clone(complexMemberSetters); }
static void EnsureIsMappingType(Type type, MethodCallExpression exp) { if (!MappingTypeSystem.IsMappingType(type)) { throw new NotSupportedException(string.Format("The generic parameter type of method {0} must be mapping type.", exp.Method.Name)); } }
public static DbParam[] BuildParams(DbContext dbContext, object parameter) { if (parameter == null) { return(new DbParam[0]); } if (parameter is IEnumerable <DbParam> ) { return(((IEnumerable <DbParam>)parameter).ToArray()); } List <DbParam> parameters = new List <DbParam>(); Type parameterType = parameter.GetType(); var props = parameterType.GetProperties(); foreach (var prop in props) { if (prop.GetGetMethod() == null || !MappingTypeSystem.IsMappingType(prop.GetMemberType())) { continue; } object value = ReflectionExtension.FastGetMemberValue(prop, parameter); string paramName = dbContext.DatabaseProvider.CreateParameterName(prop.Name); DbParam p = new DbParam(paramName, value, prop.PropertyType); parameters.Add(p); } return(parameters.ToArray()); }
IObjectActivator CreateObjectActivator(IDataReader dataReader) { Type type = typeof(T); if (type != PublicConstants.TypeOfObject && MappingTypeSystem.IsMappingType(type)) { PrimitiveObjectActivatorCreator activatorCreator = new PrimitiveObjectActivatorCreator(type, 0); return(activatorCreator.CreateObjectActivator()); } return(GetObjectActivator(type, dataReader)); }
IMappingObjectExpression VisistMapTypeSelector(Expression exp) { if (!MappingTypeSystem.IsMappingType(exp.Type)) { throw new NotSupportedException(exp.ToString()); } DbExpression dbExp = this.ResolveExpression(exp); MappingFieldExpression ret = new MappingFieldExpression(exp.Type, dbExp); return(ret); }
IObjectModel VisistMapTypeSelector(Expression exp) { if (!MappingTypeSystem.IsMappingType(exp.Type)) { throw new NotSupportedException(exp.ToString()); } DbExpression dbExp = this.ResolveExpression(exp); PrimitiveObjectModel ret = new PrimitiveObjectModel(exp.Type, dbExp); return(ret); }
/// <summary> /// a => a.Id a => a.Name a => a.User /// </summary> /// <param name="exp"></param> /// <returns></returns> protected override IMappingObjectExpression VisitMemberAccess(MemberExpression exp) { //create MappingFieldExpression object if exp is map type if (MappingTypeSystem.IsMappingType(exp.Type)) { DbExpression dbExp = this.ResolveExpression(exp); MappingFieldExpression ret = new MappingFieldExpression(exp.Type, dbExp); return(ret); } //如 a.Order a.User 等形式 return(this.ResolveComplexMember(exp)); }
protected override DbExpression VisitParameter(ParameterExpression exp) { //TODO 只支持 MappingFieldExpression 类型,即类似 q.Select(a=> a.Id).Where(a=> a > 0) 这种情况,也就是 ParameterExpression.Type 为基本映射类型。 if (MappingTypeSystem.IsMappingType(exp.Type)) { IMappingObjectExpression moe = this.FindMoe(exp); MappingFieldExpression mfe = (MappingFieldExpression)moe; return(mfe.Expression); } else { throw new NotSupportedException(exp.ToString()); } }
protected override DbExpression VisitParameter(ParameterExpression exp) { //只支持 MappingFieldExpression 类型,即类似 q.Select(a=> a.Id).Where(a=> a > 0) 这种情况,也就是 ParameterExpression.Type 为基本映射类型。 if (MappingTypeSystem.IsMappingType(exp.Type)) { IObjectModel model = this.FindModel(exp); PrimitiveObjectModel resultModel = (PrimitiveObjectModel)model; return(resultModel.Expression); } else { throw new NotSupportedException(exp.ToString()); } }
void Prepare() { Type type = typeof(T); if (MappingTypeSystem.IsMappingType(type)) { MappingField mf = new MappingField(type, 0); this._objectActivator = mf.CreateObjectActivator(); this._reader = this.ExecuteReader(); return; } this._reader = this.ExecuteReader(); this._objectActivator = GetObjectActivator(type, this._reader); }
void Prepare() { Type type = typeof(T); if (type != UtilConstants.TypeOfObject && MappingTypeSystem.IsMappingType(type)) { PrimitiveObjectActivatorCreator activatorCreator = new PrimitiveObjectActivatorCreator(type, 0); this._objectActivator = activatorCreator.CreateObjectActivator(); this._reader = this.ExecuteReader(); return; } this._reader = this.ExecuteReader(); this._objectActivator = GetObjectActivator(type, this._reader); }
async Task Prepare(bool @async) { Type type = typeof(T); if (type != PublicConstants.TypeOfObject && MappingTypeSystem.IsMappingType(type)) { PrimitiveObjectActivatorCreator activatorCreator = new PrimitiveObjectActivatorCreator(type, 0); this._objectActivator = activatorCreator.CreateObjectActivator(); this._reader = await this.ExecuteReader(@async); return; } this._reader = await this.ExecuteReader(@async); this._objectActivator = GetObjectActivator(type, this._reader); }
public EntityType(Type type) { this.Type = type; this.TableName = type.Name; PropertyInfo[] properties = this.Type.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(a => a.GetSetMethod() != null && a.GetGetMethod() != null).ToArray(); foreach (PropertyInfo property in properties) { if (!MappingTypeSystem.IsMappingType(property.PropertyType)) { continue; } this.Properties.Add(new EntityProperty(property)); } }
public static Func <IDataReader, ReaderOrdinalEnumerator, ObjectActivatorEnumerator, object> CreateObjectGenerator(ConstructorInfo constructor) { Utils.CheckNull(constructor); Func <IDataReader, ReaderOrdinalEnumerator, ObjectActivatorEnumerator, object> ret = null; var pExp_reader = Expression.Parameter(typeof(IDataReader), "reader"); var pExp_readerOrdinalEnumerator = Expression.Parameter(typeof(ReaderOrdinalEnumerator), "readerOrdinalEnumerator"); var pExp_objectActivatorEnumerator = Expression.Parameter(typeof(ObjectActivatorEnumerator), "objectActivatorEnumerator"); ParameterInfo[] parameters = constructor.GetParameters(); List <Expression> arguments = new List <Expression>(parameters.Length); foreach (ParameterInfo parameter in parameters) { if (MappingTypeSystem.IsMappingType(parameter.ParameterType)) { var readerMethod = DataReaderConstant.GetReaderMethod(parameter.ParameterType); //int ordinal = readerOrdinalEnumerator.Next(); var readerOrdinal = Expression.Call(pExp_readerOrdinalEnumerator, ReaderOrdinalEnumerator.MethodOfNext); //DataReaderExtensions.GetValue(reader,readerOrdinal) var getValue = Expression.Call(readerMethod, pExp_reader, readerOrdinal); arguments.Add(getValue); } else { //IObjectActivator oa = objectActivatorEnumerator.Next(); var oa = Expression.Call(pExp_objectActivatorEnumerator, ObjectActivatorEnumerator.MethodOfNext); //object obj = oa.CreateInstance(IDataReader reader); var entity = Expression.Call(oa, typeof(IObjectActivator).GetMethod("CreateInstance"), pExp_reader); //(T)entity; var val = Expression.Convert(entity, parameter.ParameterType); arguments.Add(val); } } var body = Expression.New(constructor, arguments); ret = Expression.Lambda <Func <IDataReader, ReaderOrdinalEnumerator, ObjectActivatorEnumerator, object> >(body, pExp_reader, pExp_readerOrdinalEnumerator, pExp_objectActivatorEnumerator).Compile(); return(ret); }
public EntityType(Type type) { this.Type = type; this.TableName = type.Name; PropertyInfo[] properties = this.Type.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(a => a.GetSetMethod() != null && a.GetGetMethod() != null).ToArray(); foreach (PropertyInfo property in properties) { MappingType mappingType; if (!MappingTypeSystem.IsMappingType(property.PropertyType, out mappingType)) { continue; } PrimitiveProperty primitiveProperty = new PrimitiveProperty(property); primitiveProperty.DbType = mappingType.DbType; primitiveProperty.IsNullable = property.PropertyType.CanNull(); if (string.Equals(property.Name, "id", StringComparison.OrdinalIgnoreCase)) { /* 默认为主键 */ primitiveProperty.IsPrimaryKey = true; if (Utils.IsAutoIncrementType(property.PropertyType)) { primitiveProperty.IsAutoIncrement = true; } if (property.PropertyType == typeof(string)) { //如果主键是 string 类型,默认为 AnsiString primitiveProperty.DbType = System.Data.DbType.AnsiString; } } this.PrimitiveProperties.Add(primitiveProperty); } }
List <MappingMemberDescriptor> ExtractMappingMemberDescriptors() { var members = this.EntityType.GetMembers(BindingFlags.Public | BindingFlags.Instance); List <MappingMemberDescriptor> mappingMemberDescriptors = new List <MappingMemberDescriptor>(); foreach (var member in members) { if (ShouldMap(member) == false) { continue; } if (MappingTypeSystem.IsMappingType(member.GetMemberType())) { MappingMemberDescriptor memberDescriptor = new MappingMemberDescriptor(member, this); mappingMemberDescriptors.Add(memberDescriptor); } } return(mappingMemberDescriptors); }
protected override IMappingObjectExpression VisitNew(NewExpression exp) { IMappingObjectExpression result = new MappingObjectExpression(exp.Constructor); ParameterInfo[] parames = exp.Constructor.GetParameters(); for (int i = 0; i < parames.Length; i++) { ParameterInfo pi = parames[i]; Expression argExp = exp.Arguments[i]; if (MappingTypeSystem.IsMappingType(pi.ParameterType)) { DbExpression dbExpression = this.ResolveExpression(argExp); result.AddMappingConstructorParameter(pi, dbExpression); } else { IMappingObjectExpression subResult = this.Visit(argExp); result.AddComplexConstructorParameter(pi, subResult); } } return(result); }
static Expression <Func <TEntity, bool> > BuildPredicate <TEntity>(object key) { /* * key: * 如果实体是单一主键,可以传入的 key 与主键属性类型相同的值,亦可以传一个包含了与实体主键类型相同的属性的对象,如:new { Id = 1 } * 如果实体是多主键,则传入的 key 须是包含了与实体主键类型相同的属性的对象,如:new { Key1 = "1", Key2 = "2" } */ Utils.CheckNull(key); Type entityType = typeof(TEntity); TypeDescriptor typeDescriptor = TypeDescriptor.GetDescriptor(entityType); EnsureEntityHasPrimaryKey(typeDescriptor); KeyValuePairList <MemberInfo, object> keyValueMap = new KeyValuePairList <MemberInfo, object>(); Type keyType = key.GetType(); if (typeDescriptor.PrimaryKeys.Count == 1 && MappingTypeSystem.IsMappingType(keyType)) { keyValueMap.Add(typeDescriptor.PrimaryKeys[0].MemberInfo, key); } else { /* * key: new { Key1 = "1", Key2 = "2" } */ object multipleKeyObject = key; Type multipleKeyObjectType = keyType; for (int i = 0; i < typeDescriptor.PrimaryKeys.Count; i++) { MappingMemberDescriptor keyMemberDescriptor = typeDescriptor.PrimaryKeys[i]; MemberInfo keyMember = multipleKeyObjectType.GetProperty(keyMemberDescriptor.MemberInfo.Name); if (keyMember == null) { throw new ArgumentException(string.Format("The input object does not define property for key '{0}'.", keyMemberDescriptor.MemberInfo.Name)); } object value = keyMember.GetMemberValue(multipleKeyObject); if (value == null) { throw new ArgumentException(string.Format("The primary key '{0}' could not be null.", keyMemberDescriptor.MemberInfo.Name)); } keyValueMap.Add(keyMemberDescriptor.MemberInfo, value); } } ParameterExpression parameter = Expression.Parameter(entityType, "a"); Expression lambdaBody = null; foreach (var keyValue in keyValueMap) { Expression propOrField = Expression.PropertyOrField(parameter, keyValue.Key.Name); Expression wrappedValue = Chloe.Extensions.ExpressionExtension.MakeWrapperAccess(keyValue.Value, keyValue.Key.GetMemberType()); Expression e = Expression.Equal(propOrField, wrappedValue); lambdaBody = lambdaBody == null ? e : Expression.AndAlso(lambdaBody, e); } Expression <Func <TEntity, bool> > predicate = Expression.Lambda <Func <TEntity, bool> >(lambdaBody, parameter); return(predicate); }
static Expression <Func <TEntity, bool> > BuildCondition <TEntity>(object key) { /* * key: * 如果实体是单一主键,可以传入的 key 与主键属性类型相同的值,亦可以传一个包含了与实体主键类型相同的属性的对象,如:new { Id = 1 } * 如果实体是多主键,则传入的 key 须是包含了与实体主键类型相同的属性的对象,如:new { Key1 = "1", Key2 = "2" } */ Utils.CheckNull(key); Type entityType = typeof(TEntity); TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(entityType); PublicHelper.EnsureHasPrimaryKey(typeDescriptor); ParameterExpression parameter = Expression.Parameter(entityType, "a"); Expression conditionBody = null; Type keyType = key.GetType(); if (typeDescriptor.PrimaryKeys.Count == 1 && MappingTypeSystem.IsMappingType(keyType)) { /* a => a.Key == key */ PropertyDescriptor keyDescriptor = typeDescriptor.PrimaryKeys[0]; Expression propOrField = Expression.PropertyOrField(parameter, keyDescriptor.Property.Name); Expression wrappedValue = ExpressionExtension.MakeWrapperAccess(key, keyDescriptor.PropertyType); conditionBody = Expression.Equal(propOrField, wrappedValue); } else { /* * key: new { Key1 = "1", Key2 = "2" } */ /* a => a.Key1 == key.Key1 && a.Key2 == key.Key2 */ Type keyObjectType = keyType; ConstantExpression keyConstantExp = Expression.Constant(key); if (keyObjectType == entityType) { foreach (PropertyDescriptor primaryKey in typeDescriptor.PrimaryKeys) { Expression propOrField = Expression.PropertyOrField(parameter, primaryKey.Property.Name); Expression keyValue = Expression.MakeMemberAccess(keyConstantExp, primaryKey.Property); Expression e = Expression.Equal(propOrField, keyValue); conditionBody = conditionBody == null ? e : Expression.AndAlso(conditionBody, e); } } else { for (int i = 0; i < typeDescriptor.PrimaryKeys.Count; i++) { PropertyDescriptor keyPropertyDescriptor = typeDescriptor.PrimaryKeys[i]; MemberInfo keyMember = keyPropertyDescriptor.Property; MemberInfo inputKeyMember = keyObjectType.GetMember(keyMember.Name).FirstOrDefault(); if (inputKeyMember == null) { throw new ArgumentException(string.Format("The input object does not define property for key '{0}'.", keyMember.Name)); } Expression propOrField = Expression.PropertyOrField(parameter, keyMember.Name); Expression keyValueExp = Expression.MakeMemberAccess(keyConstantExp, inputKeyMember); Type keyMemberType = keyMember.GetMemberType(); if (inputKeyMember.GetMemberType() != keyMemberType) { keyValueExp = Expression.Convert(keyValueExp, keyMemberType); } Expression e = Expression.Equal(propOrField, keyValueExp); conditionBody = conditionBody == null ? e : Expression.AndAlso(conditionBody, e); } } } Expression <Func <TEntity, bool> > condition = Expression.Lambda <Func <TEntity, bool> >(conditionBody, parameter); return(condition); }
protected virtual IDbCommand PrepareCommand(string cmdText, DbParam[] parameters, CommandType cmdType, out List <OutputParameter> outputParameters) { outputParameters = null; IDbCommand cmd = this.DbConnection.CreateCommand(); cmd.CommandText = cmdText; cmd.CommandType = cmdType; cmd.CommandTimeout = this.CommandTimeout; if (this.IsInTransaction) { cmd.Transaction = this.DbTransaction; } if (parameters != null) { for (int i = 0; i < parameters.Length; i++) { DbParam param = parameters[i]; if (param == null) { continue; } if (param.ExplicitParameter != null)/* 如果存在创建好了的 IDbDataParameter,则直接用它。同时也忽视了 DbParam 的其他属性 */ { cmd.Parameters.Add(param.ExplicitParameter); continue; } Type parameterType; if (param.Value == null || param.Value == DBNull.Value) { parameterType = param.Type ?? typeof(object); } else { parameterType = param.Value.GetType(); if (parameterType.IsEnum) { parameterType = Enum.GetUnderlyingType(parameterType); } } IDbDataParameter parameter = cmd.CreateParameter(); Infrastructure.MappingType mappingType; IDbParameterAssembler dbParameterAssembler = MappingTypeSystem.IsMappingType(parameterType, out mappingType) ? mappingType.DbParameterAssembler : DbParameterAssembler.Default; dbParameterAssembler.SetupParameter(parameter, param); cmd.Parameters.Add(parameter); OutputParameter outputParameter = null; if (param.Direction == ParamDirection.Output || param.Direction == ParamDirection.InputOutput) { outputParameter = new OutputParameter(param, parameter); if (outputParameters == null) { outputParameters = new List <OutputParameter>(); } outputParameters.Add(outputParameter); } } } return(cmd); }
DbExpression Process_MemberAccess_Which_Link_First_Or_FirstOrDefault(MemberExpression exp) { /* * 判断是不是 First().xx,FirstOrDefault().xx 之类的 * First().Name: 泛型参数如果不是复杂类型,则转成 Select(a=> a.Name).First() * First().xx.Name: 如果 xx 是复杂类型,则转成 Select(a=> a.xx.Name).First() * First().xx.Name.Length: 如果 xx 是复杂类型,则转成 Select(a=> a.xx.Name).First().Length */ // 分割 MethodCallExpression methodCall = null; Stack <MemberExpression> memberExps = new Stack <MemberExpression>(); Expression e = exp; while (e.NodeType == ExpressionType.MemberAccess) { MemberExpression memberExpression = (MemberExpression)e; memberExps.Push(memberExpression); e = memberExpression.Expression; } methodCall = (MethodCallExpression)e; methodCall = OptimizeCondition(methodCall); if (!MappingTypeSystem.IsMappingType(methodCall.Type)) { /* * query.First().xx.Name.Length --> query.Select(a=> a.xx.Name).First().Length */ ParameterExpression parameter = Expression.Parameter(methodCall.Type, "a"); Expression selectorBody = parameter; while (memberExps.Count != 0) { MemberExpression memberExpression = memberExps.Pop(); selectorBody = Expression.MakeMemberAccess(parameter, memberExpression.Member); if (MappingTypeSystem.IsMappingType(selectorBody.Type)) { break; } } Type delegateType = typeof(Func <,>).MakeGenericType(parameter.Type, selectorBody.Type); LambdaExpression selector = Expression.Lambda(delegateType, selectorBody, parameter); var selectMethod = methodCall.Object.Type.GetMethod("Select"); selectMethod = selectMethod.MakeGenericMethod(selectorBody.Type); var selectMethodCall = Expression.Call(methodCall.Object, selectMethod, Expression.Quote(selector)); /* query.Select(a=> a.xx.Name) */ var sameNameMethod = selectMethodCall.Type.GetMethod(methodCall.Method.Name, Type.EmptyTypes); var sameNameMethodCall = Expression.Call(selectMethodCall, sameNameMethod); /* query.Select(a=> a.xx.Name).First() */ methodCall = sameNameMethodCall; } DbExpression dbExpression = this.Visit(methodCall); while (memberExps.Count != 0) { MemberExpression memberExpression = memberExps.Pop(); dbExpression = DbExpression.MemberAccess(memberExpression.Member, dbExpression); } return(dbExpression); }