static void Method_DateTime_AddSeconds(DbMethodCallExpression exp, SqlGenerator generator) { EnsureMethodDeclaringType(exp, UtilConstants.TypeOfDateTime); DbFunction_DATEADD(generator, "SECOND", exp); }
static void Method_DbFunctions_DiffMonths(DbMethodCallExpression exp, SqlGenerator generator) { EnsureMethod(exp, UtilConstants.MethodInfo_DbFunctions_DiffMonths); throw UtilExceptions.NotSupportedMethod(exp.Method); }
public void Process(DbMethodCallExpression exp, SqlGenerator generator) { throw UtilExceptions.NotSupportedMethod(exp.Method); }
static void Method_LongCount(DbMethodCallExpression exp, SqlGenerator generator) { EnsureMethodDeclaringType(exp, typeof(AggregateFunctions)); Aggregate_LongCount(generator); }
static void Method_Guid_NewGuid(DbMethodCallExpression exp, SqlGenerator generator) { EnsureMethod(exp, UtilConstants.MethodInfo_Guid_NewGuid); generator._sqlBuilder.Append("NEWID()"); }
static void Method_DbFunctions_DiffMicroseconds(DbMethodCallExpression exp, SqlGenerator generator) { EnsureMethod(exp, UtilConstants.MethodInfo_DbFunctions_DiffMicroseconds); DbFunction_DATEDIFF(generator, "MICROSECOND", exp.Arguments[0], exp.Arguments[1]); }
public void Process(DbMethodCallExpression exp, SqlGenerator generator) { generator.SqlBuilder.Append("LOWER("); exp.Object.Accept(generator); generator.SqlBuilder.Append(")"); }
public override DbExpression Visit(DbNotEqualExpression exp) { DbExpression left = exp.Left; DbExpression right = exp.Right; left = DbExpressionExtension.StripInvalidConvert(left); right = DbExpressionExtension.StripInvalidConvert(right); MethodInfo method_Sql_NotEquals = PublicConstants.MethodInfo_Sql_NotEquals.MakeGenericMethod(left.Type); /* Sql.NotEquals(left, right) */ DbMethodCallExpression left_not_equals_right = DbExpression.MethodCall(null, method_Sql_NotEquals, new List <DbExpression>(2) { left, right }); //明确 left right 其中一边一定为 null if (DbExpressionHelper.AffirmExpressionRetValueIsNullOrEmpty(right) || DbExpressionHelper.AffirmExpressionRetValueIsNullOrEmpty(left)) { /* * a.Name != null --> a.Name != null */ left_not_equals_right.Accept(this); return(exp); } if (right.NodeType == DbExpressionType.SubQuery || left.NodeType == DbExpressionType.SubQuery) { /* * a.Id != (select top 1 T.Id from T) --> a.Id <> (select top 1 T.Id from T),对于这种查询,我们不考虑 null */ left_not_equals_right.Accept(this); return(exp); } MethodInfo method_Sql_Equals = PublicConstants.MethodInfo_Sql_Equals.MakeGenericMethod(left.Type); if (left.NodeType == DbExpressionType.Parameter || left.NodeType == DbExpressionType.Constant) { var t = right; right = left; left = t; } if (right.NodeType == DbExpressionType.Parameter || right.NodeType == DbExpressionType.Constant) { /* * 走到这说明 name 不可能为 null * a.Name != name --> a.Name <> name or a.Name is null */ if (left.NodeType != DbExpressionType.Parameter && left.NodeType != DbExpressionType.Constant) { /* * a.Name != name --> a.Name <> name or a.Name is null */ /* Sql.Equals(left, null) */ var left_is_null1 = DbExpression.MethodCall(null, method_Sql_Equals, new List <DbExpression>(2) { left, DbExpression.Constant(null, left.Type) }); /* Sql.NotEquals(left, right) || Sql.Equals(left, null) */ var left_not_equals_right_or_left_is_null = DbExpression.Or(left_not_equals_right, left_is_null1); left_not_equals_right_or_left_is_null.Accept(this); } else { /* * name != name1 --> name <> name,其中 name 和 name1 都为变量且都不可能为 null */ left_not_equals_right.Accept(this); } return(exp); } /* * a.Name != a.XName --> a.Name <> a.XName or (a.Name is null and a.XName is not null) or (a.Name is not null and a.XName is null) * ## a.Name != a.XName 不能翻译成:not (a.Name == a.XName or (a.Name is null and a.XName is null)),因为数据库里的 not 有时候并非真正意义上的“取反”! * 当 a.Name 或者 a.XName 其中一个字段有为 NULL,另一个字段有值时,会查不出此条数据 ## */ DbConstantExpression null_Constant = DbExpression.Constant(null, left.Type); /* Sql.Equals(left, null) */ var left_is_null = DbExpression.MethodCall(null, method_Sql_Equals, new List <DbExpression>(2) { left, null_Constant }); /* Sql.NotEquals(left, null) */ var left_is_not_null = DbExpression.MethodCall(null, method_Sql_NotEquals, new List <DbExpression>(2) { left, null_Constant }); /* Sql.Equals(right, null) */ var right_is_null = DbExpression.MethodCall(null, method_Sql_Equals, new List <DbExpression>(2) { right, null_Constant }); /* Sql.NotEquals(right, null) */ var right_is_not_null = DbExpression.MethodCall(null, method_Sql_NotEquals, new List <DbExpression>(2) { right, null_Constant }); /* Sql.Equals(left, null) && Sql.NotEquals(right, null) */ var left_is_null_and_right_is_not_null = DbExpression.And(left_is_null, right_is_not_null); /* Sql.NotEquals(left, null) && Sql.Equals(right, null) */ var left_is_not_null_and_right_is_null = DbExpression.And(left_is_not_null, right_is_null); /* (Sql.Equals(left, null) && Sql.NotEquals(right, null)) || (Sql.NotEquals(left, null) && Sql.Equals(right, null)) */ var left_is_null_and_right_is_not_null_or_left_is_not_null_and_right_is_null = DbExpression.Or(left_is_null_and_right_is_not_null, left_is_not_null_and_right_is_null); /* Sql.NotEquals(left, right) || (Sql.Equals(left, null) && Sql.NotEquals(right, null)) || (Sql.NotEquals(left, null) && Sql.Equals(right, null)) */ var e = DbExpression.Or(left_not_equals_right, left_is_null_and_right_is_not_null_or_left_is_not_null_and_right_is_null); e.Accept(this); return(exp); }
public void Process(DbMethodCallExpression exp, SqlGenerator generator) { throw new NotSupportedException(MethodHandlerHelper.AppendNotSupportedDbFunctionsMsg(exp.Method, "TotalDays")); }
public void Process(DbMethodCallExpression exp, SqlGenerator generator) { exp.Object.Accept(generator); generator.SqlBuilder.Append(" LIKE '%' + "); exp.Arguments.First().Accept(generator); }
public void Process(DbMethodCallExpression exp, SqlGenerator generator) { SqlGenerator.DbFunction_DATEDIFF(generator, "MONTH", exp.Arguments[0], exp.Arguments[1]); }
/// <summary> /// 是否可以将 exp.Method 翻译成数据库对应的语法 /// </summary> /// <param name="exp"></param> /// <returns></returns> public virtual bool CanTranslateToSql(DbMethodCallExpression exp) { return(false); }
public void Process(DbMethodCallExpression exp, SqlGenerator generator) { generator.SqlBuilder.Append("NEWID()"); }
public override TEntity Insert <TEntity>(TEntity entity, string table) { PublicHelper.CheckNull(entity); TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(typeof(TEntity)); DbTable dbTable = PublicHelper.CreateDbTable(typeDescriptor, table); Dictionary <PrimitivePropertyDescriptor, object> keyValueMap = PrimaryKeyHelper.CreateKeyValueMap(typeDescriptor); Dictionary <PrimitivePropertyDescriptor, DbExpression> insertColumns = new Dictionary <PrimitivePropertyDescriptor, DbExpression>(); foreach (PrimitivePropertyDescriptor propertyDescriptor in typeDescriptor.PrimitivePropertyDescriptors) { if (propertyDescriptor.IsAutoIncrement) { continue; } if (propertyDescriptor.HasSequence()) { DbMethodCallExpression getNextValueForSequenceExp = PublicHelper.MakeNextValueForSequenceDbExpression(propertyDescriptor, dbTable.Schema); insertColumns.Add(propertyDescriptor, getNextValueForSequenceExp); continue; } object val = propertyDescriptor.GetValue(entity); PublicHelper.NotNullCheck(propertyDescriptor, val); if (propertyDescriptor.IsPrimaryKey) { keyValueMap[propertyDescriptor] = val; } DbParameterExpression valExp = DbExpression.Parameter(val, propertyDescriptor.PropertyType, propertyDescriptor.Column.DbType); insertColumns.Add(propertyDescriptor, valExp); } PrimitivePropertyDescriptor nullValueKey = keyValueMap.Where(a => a.Value == null && !a.Key.IsAutoIncrement).Select(a => a.Key).FirstOrDefault(); if (nullValueKey != null) { /* 主键为空并且主键又不是自增列 */ throw new ChloeException(string.Format("The primary key '{0}' could not be null.", nullValueKey.Property.Name)); } DbInsertExpression insertExp = new DbInsertExpression(dbTable); foreach (var kv in insertColumns) { insertExp.InsertColumns.Add(kv.Key.Column, kv.Value); } List <Action <TEntity, IDataReader> > mappers = new List <Action <TEntity, IDataReader> >(); foreach (var item in typeDescriptor.PrimitivePropertyDescriptors.Where(a => a.IsAutoIncrement || a.HasSequence())) { mappers.Add(GetMapper <TEntity>(item, insertExp.Returns.Count)); insertExp.Returns.Add(item.Column); } if (mappers.Count == 0) { this.ExecuteNonQuery(insertExp); return(entity); } IDbExpressionTranslator translator = this.DatabaseProvider.CreateDbExpressionTranslator(); List <DbParam> parameters; string sql = translator.Translate(insertExp, out parameters); IDataReader dataReader = this.Session.ExecuteReader(sql, parameters.ToArray()); using (dataReader) { dataReader.Read(); foreach (var mapper in mappers) { mapper(entity, dataReader); } } return(entity); }
public bool CanProcess(DbMethodCallExpression exp) { return(exp.Method.DeclaringType == PublicConstants.TypeOfSql); }
bool IsDateSubtract(DbMemberExpression exp) { MemberInfo member = exp.Member; if (member.DeclaringType == PublicConstants.TypeOfTimeSpan) { if (exp.Expression.NodeType == DbExpressionType.Call) { DbMethodCallExpression dbMethodExp = (DbMethodCallExpression)exp.Expression; if (dbMethodExp.Method == PublicConstants.MethodInfo_DateTime_Subtract_DateTime) { int?intervalDivisor = null; if (member == UtilConstants.PropertyInfo_TimeSpan_TotalDays) { intervalDivisor = 24 * 60 * 60 * 1000; goto appendIntervalTime; } if (member == UtilConstants.PropertyInfo_TimeSpan_TotalHours) { intervalDivisor = 60 * 60 * 1000; goto appendIntervalTime; } if (member == UtilConstants.PropertyInfo_TimeSpan_TotalMinutes) { intervalDivisor = 60 * 1000; goto appendIntervalTime; } if (member == UtilConstants.PropertyInfo_TimeSpan_TotalSeconds) { intervalDivisor = 1000; goto appendIntervalTime; } if (member == UtilConstants.PropertyInfo_TimeSpan_TotalMilliseconds) { intervalDivisor = 1; goto appendIntervalTime; } return(false); appendIntervalTime: this.CalcDateDiffPrecise(dbMethodExp.Object, dbMethodExp.Arguments[0], intervalDivisor.Value); return(true); } } else { DbSubtractExpression dbSubtractExp = exp.Expression as DbSubtractExpression; if (dbSubtractExp != null && dbSubtractExp.Left.Type == PublicConstants.TypeOfDateTime && dbSubtractExp.Right.Type == PublicConstants.TypeOfDateTime) { DbMethodCallExpression dbMethodExp = new DbMethodCallExpression(dbSubtractExp.Left, PublicConstants.MethodInfo_DateTime_Subtract_DateTime, new List <DbExpression>(1) { dbSubtractExp.Right }); DbMemberExpression dbMemberExp = DbExpression.MemberAccess(member, dbMethodExp); dbMemberExp.Accept(this); return(true); } } } return(false); }
public void Process(DbMethodCallExpression exp, SqlGeneratorBase generator) { DbExpression left = exp.Arguments[0]; DbExpression right = exp.Arguments[2]; CompareType compareType = (CompareType)exp.Arguments[1].Evaluate(); DbExpression newExp = null; switch (compareType) { case CompareType.eq: { MethodInfo method_Sql_Equals = PublicConstants.MethodInfo_Sql_Equals.MakeGenericMethod(left.Type); /* Sql.Equals(left, right) */ DbMethodCallExpression left_equals_right = DbExpression.MethodCall(null, method_Sql_Equals, new List <DbExpression>(2) { left, right }); newExp = left_equals_right; } break; case CompareType.neq: { MethodInfo method_Sql_NotEquals = PublicConstants.MethodInfo_Sql_NotEquals.MakeGenericMethod(left.Type); /* Sql.NotEquals(left, right) */ DbMethodCallExpression left_not_equals_right = DbExpression.MethodCall(null, method_Sql_NotEquals, new List <DbExpression>(2) { left, right }); newExp = left_not_equals_right; } break; case CompareType.gt: { newExp = new DbGreaterThanExpression(left, right); } break; case CompareType.gte: { newExp = new DbGreaterThanOrEqualExpression(left, right); } break; case CompareType.lt: { newExp = new DbLessThanExpression(left, right); } break; case CompareType.lte: { newExp = new DbLessThanOrEqualExpression(left, right); } break; default: throw new NotSupportedException("CompareType: " + compareType.ToString()); } newExp.Accept(generator); }
public void Process(DbMethodCallExpression exp, SqlGenerator generator) { SqlGenerator.DbFunction_DATEADD(generator, "MINUTE", exp); }
public void Process(DbMethodCallExpression exp, SqlGenerator generator) { SqlGenerator.Aggregate_LongCount(generator); }
static void Method_DbFunctions_DiffMinutes(DbMethodCallExpression exp, SqlGenerator generator) { EnsureMethod(exp, UtilConstants.MethodInfo_DbFunctions_DiffMinutes); DbFunction_DATEDIFF(generator, "MINUTE", exp.Arguments[0], exp.Arguments[1]); }
public override object Insert <TEntity>(Expression <Func <TEntity> > content, string table) { PublicHelper.CheckNull(content); TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(typeof(TEntity)); if (typeDescriptor.PrimaryKeys.Count > 1) { /* 对于多主键的实体,暂时不支持调用这个方法进行插入 */ throw new NotSupportedException(string.Format("Can not call this method because entity '{0}' has multiple keys.", typeDescriptor.Definition.Type.FullName)); } PropertyDescriptor keyPropertyDescriptor = typeDescriptor.PrimaryKeys.FirstOrDefault(); Dictionary <MemberInfo, Expression> insertColumns = InitMemberExtractor.Extract(content); DbTable explicitDbTable = null; if (table != null) { explicitDbTable = new DbTable(table, typeDescriptor.Table.Schema); } DefaultExpressionParser expressionParser = typeDescriptor.GetExpressionParser(explicitDbTable); DbInsertExpression insertExp = new DbInsertExpression(explicitDbTable ?? typeDescriptor.Table); object keyVal = null; foreach (var kv in insertColumns) { MemberInfo key = kv.Key; PropertyDescriptor propertyDescriptor = typeDescriptor.TryGetPropertyDescriptor(key); if (propertyDescriptor == null) { throw new ChloeException(string.Format("The member '{0}' does not map any column.", key.Name)); } if (propertyDescriptor.IsAutoIncrement) { throw new ChloeException(string.Format("Could not insert value into the identity column '{0}'.", propertyDescriptor.Column.Name)); } if (propertyDescriptor.HasSequence()) { throw new ChloeException(string.Format("Can not insert value into the column '{0}', because it's mapping member has define a sequence.", propertyDescriptor.Column.Name)); } if (propertyDescriptor.IsPrimaryKey) { object val = ExpressionEvaluator.Evaluate(kv.Value); if (val == null) { throw new ChloeException(string.Format("The primary key '{0}' could not be null.", propertyDescriptor.Property.Name)); } else { keyVal = val; insertExp.InsertColumns.Add(propertyDescriptor.Column, DbExpression.Parameter(keyVal, propertyDescriptor.PropertyType, propertyDescriptor.Column.DbType)); continue; } } insertExp.InsertColumns.Add(propertyDescriptor.Column, expressionParser.Parse(kv.Value)); } foreach (var item in typeDescriptor.PropertyDescriptors.Where(a => a.HasSequence())) { DbMethodCallExpression getNextValueForSequenceExp = PublicHelper.MakeNextValueForSequenceDbExpression(item); insertExp.InsertColumns.Add(item.Column, getNextValueForSequenceExp); } if (keyPropertyDescriptor != null) { //主键为空并且主键又不是自增列 if (keyVal == null && !keyPropertyDescriptor.IsAutoIncrement && !keyPropertyDescriptor.HasSequence()) { throw new ChloeException(string.Format("The primary key '{0}' could not be null.", keyPropertyDescriptor.Property.Name)); } } if (keyPropertyDescriptor == null) { this.ExecuteNonQuery(insertExp); return(keyVal); /* It will return null if an entity does not define primary key. */ } if (!keyPropertyDescriptor.IsAutoIncrement && !keyPropertyDescriptor.HasSequence()) { this.ExecuteNonQuery(insertExp); return(keyVal); } IDbExpressionTranslator translator = this.DatabaseProvider.CreateDbExpressionTranslator(); List <DbParam> parameters; string sql = translator.Translate(insertExp, out parameters); if (keyPropertyDescriptor.IsAutoIncrement) { /* 自增 id 不能用 output inserted.Id 输出,因为如果表设置了触发器的话会报错 */ sql = string.Concat(sql, ";", this.GetSelectLastInsertIdClause()); } else if (keyPropertyDescriptor.HasSequence()) { insertExp.Returns.Add(keyPropertyDescriptor.Column); } object ret = this.Session.ExecuteScalar(sql, parameters.ToArray()); if (ret == null || ret == DBNull.Value) { throw new ChloeException("Unable to get the identity/sequence value."); } ret = PublicHelper.ConvertObjType(ret, typeDescriptor.AutoIncrement.PropertyType); return(ret); }
public void Process(DbMethodCallExpression exp, SqlGenerator generator) { SqlGenerator.Aggregate_Max(generator, exp.Arguments.First(), exp.Method.ReturnType); }
public override TEntity Insert <TEntity>(TEntity entity, string table) { PublicHelper.CheckNull(entity); TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(typeof(TEntity)); Dictionary <PropertyDescriptor, object> keyValueMap = PrimaryKeyHelper.CreateKeyValueMap(typeDescriptor); Dictionary <PropertyDescriptor, DbExpression> insertColumns = new Dictionary <PropertyDescriptor, DbExpression>(); List <PropertyDescriptor> outputColumns = new List <PropertyDescriptor>(); foreach (PropertyDescriptor propertyDescriptor in typeDescriptor.PropertyDescriptors) { if (propertyDescriptor.IsAutoIncrement || propertyDescriptor.IsTimestamp()) { outputColumns.Add(propertyDescriptor); continue; } if (propertyDescriptor.HasSequence()) { DbMethodCallExpression getNextValueForSequenceExp = PublicHelper.MakeNextValueForSequenceDbExpression(propertyDescriptor); insertColumns.Add(propertyDescriptor, getNextValueForSequenceExp); outputColumns.Add(propertyDescriptor); continue; } object val = propertyDescriptor.GetValue(entity); if (propertyDescriptor.IsPrimaryKey) { keyValueMap[propertyDescriptor] = val; } DbExpression valExp = DbExpression.Parameter(val, propertyDescriptor.PropertyType, propertyDescriptor.Column.DbType); insertColumns.Add(propertyDescriptor, valExp); } PropertyDescriptor nullValueKey = keyValueMap.Where(a => a.Value == null && !a.Key.IsAutoIncrement).Select(a => a.Key).FirstOrDefault(); if (nullValueKey != null) { /* 主键为空并且主键又不是自增列 */ throw new ChloeException(string.Format("The primary key '{0}' could not be null.", nullValueKey.Property.Name)); } DbTable dbTable = table == null ? typeDescriptor.Table : new DbTable(table, typeDescriptor.Table.Schema); DbInsertExpression insertExp = new DbInsertExpression(dbTable); foreach (var kv in insertColumns) { insertExp.InsertColumns.Add(kv.Key.Column, kv.Value); } if (outputColumns.Count == 0) { this.ExecuteNonQuery(insertExp); return(entity); } List <Action <TEntity, IDataReader> > mappers = new List <Action <TEntity, IDataReader> >(); IDbExpressionTranslator translator = this.DatabaseProvider.CreateDbExpressionTranslator(); List <DbParam> parameters; string sql = null; if (outputColumns.Count == 1 && outputColumns[0].IsAutoIncrement) { sql = translator.Translate(insertExp, out parameters); /* 自增 id 不能用 output inserted.Id 输出,因为如果表设置了触发器的话会报错 */ sql = string.Concat(sql, ";", this.GetSelectLastInsertIdClause()); mappers.Add(GetMapper <TEntity>(outputColumns[0], 0)); } else { foreach (PropertyDescriptor outputColumn in outputColumns) { mappers.Add(GetMapper <TEntity>(outputColumn, insertExp.Returns.Count)); insertExp.Returns.Add(outputColumn.Column); } sql = translator.Translate(insertExp, out parameters); } IDataReader dataReader = this.Session.ExecuteReader(sql, parameters.ToArray()); using (dataReader) { dataReader.Read(); foreach (var mapper in mappers) { mapper(entity, dataReader); } } return(entity); }
public bool CanProcess(DbMethodCallExpression exp) { return(exp.Method.DeclaringType.IsGenericType && exp.Method.DeclaringType.GetGenericTypeDefinition() == typeof(Then <>)); }
static void Method_Guid_NewGuid(DbMethodCallExpression exp, SqlGenerator generator) { EnsureMethod(exp, UtilConstants.MethodInfo_Guid_NewGuid); throw UtilExceptions.NotSupportedMethod(exp.Method); }
static void Method_Average(DbMethodCallExpression exp, SqlGenerator generator) { EnsureMethodDeclaringType(exp, typeof(AggregateFunctions)); Aggregate_Average(generator, exp.Arguments.First(), exp.Method.ReturnType); }
static void Method_DbFunctions_DiffYears(DbMethodCallExpression exp, SqlGenerator generator) { EnsureMethod(exp, UtilConstants.MethodInfo_DbFunctions_DiffYears); Append_DiffYears(generator, exp.Arguments[0], exp.Arguments[1]); }
static void Method_DateTime_AddMilliseconds(DbMethodCallExpression exp, SqlGenerator generator) { EnsureMethodDeclaringType(exp, UtilConstants.TypeOfDateTime); throw UtilExceptions.NotSupportedMethod(exp.Method); }
static void Method_DbFunctions_DiffSeconds(DbMethodCallExpression exp, SqlGenerator generator) { EnsureMethod(exp, UtilConstants.MethodInfo_DbFunctions_DiffSeconds); Append_DateDiff(generator, exp.Arguments[0], exp.Arguments[1], 24 * 60 * 60); }
public static bool ExpressionEquals(DbMethodCallExpression exp1, DbMethodCallExpression exp2) { if (exp1.Method != exp2.Method) return false; if (exp1.Arguments.Count != exp2.Arguments.Count) return false; if (!EqualsCompare(exp1.Object, exp2.Object)) return false; for (int i = 0; i < exp1.Arguments.Count; i++) { if (!EqualsCompare(exp1.Arguments[i], exp2.Arguments[i])) return false; } return true; }
public void Process(DbMethodCallExpression exp, SqlGenerator generator) { SqlGenerator.Append_DiffYears(generator, exp.Arguments[0], exp.Arguments[1]); }