internal Binding(Expression linqExpression, DbExpression cqtExpression) { //Contract.Requires(linqExpression != null); //Contract.Requires(cqtExpression != null); LinqExpression = linqExpression; CqtExpression = cqtExpression; }
private DbExpression Process(DbExpression expression) { DebugCheck.NotNull(expression); expression = VisitExpression(expression); return expression; }
internal DbGroupExpressionBinding( DbExpression input, DbVariableReferenceExpression inputRef, DbVariableReferenceExpression groupRef) { _expr = input; _varRef = inputRef; _groupVarRef = groupRef; }
public static DbExpression StripInvalidConvert(DbExpression exp) { DbConvertExpression convertExpression = exp as DbConvertExpression; if (convertExpression == null) return exp; if (convertExpression.Type.IsEnum) { //(enumType)123 if (typeof(int) == convertExpression.Operand.Type) return StripInvalidConvert(convertExpression.Operand); DbConvertExpression newExp = new DbConvertExpression(typeof(int), convertExpression.Operand); return StripInvalidConvert(newExp); } Type unType; //(int?)123 if (Utils.IsNullable(convertExpression.Type, out unType))//可空类型转换 { if (unType == convertExpression.Operand.Type) return StripInvalidConvert(convertExpression.Operand); DbConvertExpression newExp = new DbConvertExpression(unType, convertExpression.Operand); return StripInvalidConvert(newExp); } //(int)enumTypeValue if (exp.Type == typeof(int)) { //(int)enumTypeValue if (convertExpression.Operand.Type.IsEnum) return StripInvalidConvert(convertExpression.Operand); //(int)NullableEnumTypeValue if (Utils.IsNullable(convertExpression.Operand.Type, out unType) && unType.IsEnum) return StripInvalidConvert(convertExpression.Operand); } //float long double and so on if (exp.Type.IsValueType) { //(long)NullableValue if (Utils.IsNullable(convertExpression.Operand.Type, out unType) && unType == exp.Type) return StripInvalidConvert(convertExpression.Operand); } if (convertExpression.Type == convertExpression.Operand.Type) { return StripInvalidConvert(convertExpression.Operand); } //如果是子类向父类转换 if (exp.Type.IsAssignableFrom(convertExpression.Operand.Type)) return StripInvalidConvert(convertExpression.Operand); return convertExpression; }
public static FieldDescription[] GetReturningFields( DbExpression returning) { // Find the returning properties DbNewInstanceExpression returnExpression = returning as DbNewInstanceExpression; if (returnExpression == null) { throw new NotSupportedException( "The type of the Returning properties is not DbNewInstanceExpression"); } List<FieldDescription> result = new List<FieldDescription>(); // Add the returning property names foreach (DbPropertyExpression propertyExpression in returnExpression.Arguments) { PrimitiveType propertyType = propertyExpression.ResultType.EdmType as PrimitiveType; string name = propertyExpression.Property.GetColumnName(); Type type = propertyType.ClrEquivalentType; result.Add(new FieldDescription(name, type)); } return result.ToArray(); }
internal static CqtExpression StripNull(LinqExpression sourceExpression, DbExpression inputExpression, DbExpression outputExpression, bool useDatabaseNullSemantics) { if (sourceExpression.IsNullConstant()) { return DbExpressionBuilder.Constant(string.Empty); } if (sourceExpression.NodeType == ExpressionType.Constant) { return outputExpression; } if (useDatabaseNullSemantics) { return outputExpression; } // converts evaluated null values to empty string, nullable primitive properties etc. var castNullToEmptyString = DbExpressionBuilder.Case( new[] { inputExpression.IsNull() }, new[] { DbExpressionBuilder.Constant(string.Empty) }, outputExpression); return castNullToEmptyString; }
internal DbDeleteCommandTree(MetadataWorkspace metadata, DataSpace dataSpace, DbExpressionBinding target, DbExpression predicate) : base(metadata, dataSpace, target) { EntityUtil.CheckArgumentNull(predicate, "predicate"); this._predicate = predicate; }
internal DbDeleteCommandTree(MetadataWorkspace metadata, DataSpace dataSpace, DbExpressionBinding target, DbExpression predicate) : base(metadata, dataSpace, target) { Contract.Requires(predicate != null); _predicate = predicate; }
/// <summary> /// Initializes a new instance of the <see cref="DbDeleteCommandTree"/> class. /// </summary> /// <param name="metadata">The model this command will operate on.</param> /// <param name="dataSpace">The data space.</param> /// <param name="target">The target table for the data manipulation language (DML) operation.</param> /// <param name="predicate">A predicate used to determine which members of the target collection should be deleted.</param> public DbDeleteCommandTree(MetadataWorkspace metadata, DataSpace dataSpace, DbExpressionBinding target, DbExpression predicate) : base(metadata, dataSpace, target) { DebugCheck.NotNull(predicate); _predicate = predicate; }
protected override SelectStatement GenerateReturningSql(DbModificationCommandTree tree, DbExpression returning) { SelectStatement select = base.GenerateReturningSql(tree, returning); ListFragment where = new ListFragment(); EntitySetBase table = ((DbScanExpression)tree.Target.Expression).Target; bool foundIdentity = false; where.Append(" row_count() > 0"); foreach (EdmMember keyMember in table.ElementType.KeyMembers) { SqlFragment value; if (!values.TryGetValue(keyMember, out value)) { if (foundIdentity) throw new NotSupportedException(); foundIdentity = true; PrimitiveTypeKind type = ((PrimitiveType)keyMember.TypeUsage.EdmType.BaseType).PrimitiveTypeKind; if ((type == PrimitiveTypeKind.Byte) || (type == PrimitiveTypeKind.SByte) || (type == PrimitiveTypeKind.Int16) || (type == PrimitiveTypeKind.Int32) || (type == PrimitiveTypeKind.Int64)) { value = new LiteralFragment("last_insert_id()"); } else if (keyMember.TypeUsage.EdmType.BaseType.Name == "Guid") value = new LiteralFragment(string.Format("ANY(SELECT guid FROM tmpIdentity_{0})", (table as MetadataItem).MetadataProperties["Table"].Value)); } where.Append(String.Format(" AND `{0}`=", keyMember)); where.Append(value); } select.Where = where; return select; }
internal static bool TryRewrite(DbQueryCommandTree tree, Span span, MergeOption mergeOption, AliasGenerator aliasGenerator, out DbExpression newQuery, out SpanIndex spanInfo) { newQuery = null; spanInfo = null; ObjectSpanRewriter rewriter = null; bool requiresRelationshipSpan = Span.RequiresRelationshipSpan(mergeOption); // Potentially perform a rewrite for span. // Note that the public 'Span' property is NOT used to retrieve the Span instance // since this forces creation of a Span object that may not be required. if (span != null && span.SpanList.Count > 0) { rewriter = new ObjectFullSpanRewriter(tree, tree.Query, span, aliasGenerator); } else if (requiresRelationshipSpan) { rewriter = new ObjectSpanRewriter(tree, tree.Query, aliasGenerator); } if (rewriter != null) { rewriter.RelationshipSpan = requiresRelationshipSpan; newQuery = rewriter.RewriteQuery(); if (newQuery != null) { Debug.Assert(rewriter.SpanIndex != null || tree.Query.ResultType.EdmEquals(newQuery.ResultType), "Query was rewritten for Span but no SpanIndex was created?"); spanInfo = rewriter.SpanIndex; } } return (spanInfo != null); }
protected virtual SelectStatement GenerateReturningSql(DbModificationCommandTree tree, DbExpression returning) { SelectStatement select = base.GenerateReturningSql(tree, returning); ListFragment where = new ListFragment(); EntitySetBase table = ((DbScanExpression)tree.Target.Expression).Target; bool foundIdentity = false; where.Append(" row_count() > 0"); foreach (EdmMember keyMember in table.ElementType.KeyMembers) { SqlFragment value; if (!values.TryGetValue(keyMember, out value)) { if (foundIdentity) throw new NotSupportedException(); foundIdentity = true; value = new LiteralFragment("last_insert_id()"); } where.Append(String.Format(" AND `{0}`=", keyMember)); where.Append(value); } select.Where = where; return select; }
internal DbSetClause(DbExpression targetProperty, DbExpression sourceValue) { //Contract.Requires(targetProperty != null); //Contract.Requires(sourceValue != null); _prop = targetProperty; _val = sourceValue; }
internal DbUnaryExpression(DbExpressionKind kind, TypeUsage resultType, DbExpression argument) : base(kind, resultType) { Debug.Assert(argument != null, "DbUnaryExpression.Argument cannot be null"); _argument = argument; }
internal DbUnaryExpression(DbExpressionKind kind, TypeUsage resultType, DbExpression argument) : base(kind, resultType) { DebugCheck.NotNull(argument); _argument = argument; }
private static Tuple<DbExpression, DbExpressionRule.ProcessedAction> ProcessRules( DbExpression expression, List<DbExpressionRule> rules) { // Considering each rule in the rule set in turn, if the rule indicates that it can process the // input expression, call TryProcess to attempt processing. If successful, take the action specified // by the rule's OnExpressionProcessed action, which may involve returning the action and the result // expression so that processing can be reset or halted. for (var idx = 0; idx < rules.Count; idx++) { var currentRule = rules[idx]; if (currentRule.ShouldProcess(expression)) { DbExpression result; if (currentRule.TryProcess(expression, out result)) { if (currentRule.OnExpressionProcessed != DbExpressionRule.ProcessedAction.Continue) { return Tuple.Create(result, currentRule.OnExpressionProcessed); } else { expression = result; } } } } return Tuple.Create(expression, DbExpressionRule.ProcessedAction.Continue); }
internal DbSortClause(DbExpression key, bool asc, string collation) { Debug.Assert(key != null, "DbSortClause key cannot be null"); _expr = key; _asc = asc; _coll = collation; }
/// <summary> /// Constructs a new ObjectSpanRewriter that will attempt to apply spanning to the specified query /// (represented as a DbExpression) when <see cref="RewriteQuery" /> is called. /// </summary> /// <param name="toRewrite"> A <see cref="DbExpression" /> representing the query to span. </param> internal ObjectSpanRewriter(DbCommandTree tree, DbExpression toRewrite, AliasGenerator aliasGenerator) { Debug.Assert(toRewrite != null, "Expression to rewrite cannot be null"); _toRewrite = toRewrite; _tree = tree; _aliasGenerator = aliasGenerator; }
internal DbSortClause(DbExpression key, bool asc, string collation) { DebugCheck.NotNull(key); _expr = key; _asc = asc; _coll = collation; }
/// <summary> /// Constructs a new ObjectSpanRewriter that will attempt to apply spanning to the specified query /// (represented as a DbExpression) when <see cref="RewriteQuery" /> is called. /// </summary> /// <param name="toRewrite"> /// A <see cref="DbExpression" /> representing the query to span. /// </param> internal ObjectSpanRewriter(DbCommandTree tree, DbExpression toRewrite, AliasGenerator aliasGenerator) { DebugCheck.NotNull(toRewrite); _toRewrite = toRewrite; _tree = tree; _aliasGenerator = aliasGenerator; }
internal DbRelatedEntityRef AsCqt(DbExpression row) { return DbExpressionBuilder.CreateRelatedEntityRef( m_fromEnd, m_toEnd, m_toEndEntitySet.CreateRef( m_toEndEntityType, m_toEndEntityKeyMemberPaths.Select(keyMember => row.Property(keyMember.CqlFieldAlias)))); }
internal DbExpressionBinding(DbExpression input, DbVariableReferenceExpression varRef) { Debug.Assert(input != null, "DbExpressionBinding input cannot be null"); Debug.Assert(varRef != null, "DbExpressionBinding variable cannot be null"); _expr = input; _varRef = varRef; }
internal DbExpressionBinding(DbExpression input, DbVariableReferenceExpression varRef) { DebugCheck.NotNull(input); DebugCheck.NotNull(varRef); _expr = input; _varRef = varRef; }
internal DbSetClause(DbExpression targetProperty, DbExpression sourceValue) : base() { EntityUtil.CheckArgumentNull(targetProperty, "targetProperty"); EntityUtil.CheckArgumentNull(sourceValue, "sourceValue"); _prop = targetProperty; _val = sourceValue; }
public EntitySetBase[] Search(DbExpression expression) { this.tables.Clear(); this.Visit(expression); return this.tables.ToArray(); }
internal DbLambda(ReadOnlyVariables variables, DbExpression bodyExp) { DebugCheck.NotNull(variables); DebugCheck.NotNull(bodyExp); _variables = variables; _body = bodyExp; }
internal Binding(Expression linqExpression, DbExpression cqtExpression) { DebugCheck.NotNull(linqExpression); DebugCheck.NotNull(cqtExpression); LinqExpression = linqExpression; CqtExpression = cqtExpression; }
internal DbLambda(ReadOnlyVariables variables, DbExpression bodyExp) { Debug.Assert(variables != null, "DbLambda.Variables cannot be null"); Debug.Assert(bodyExp != null, "DbLambda.Body cannot be null"); _variables = variables; _body = bodyExp; }
internal DbSetClause(DbExpression targetProperty, DbExpression sourceValue) { DebugCheck.NotNull(targetProperty); DebugCheck.NotNull(sourceValue); _prop = targetProperty; _val = sourceValue; }
internal DbBinaryExpression(DbExpressionKind kind, TypeUsage type, DbExpression left, DbExpression right) : base(kind, type) { DebugCheck.NotNull(left); DebugCheck.NotNull(right); _left = left; _right = right; }
public void AddMemberExpression(MemberInfo p, DbExpression exp) { throw new NotSupportedException(); }
internal DbExpressionEntitySetInfo VisitExpression(DbExpression expression) { return(expression.Accept(this)); }
static bool IsApplyOrJoinExpression(DbExpression e) { return(IsApplyExpression(e) || IsJoinExpression(e)); }
public virtual object Insert <TEntity>(Expression <Func <TEntity> > body) { Utils.CheckNull(body); TypeDescriptor typeDescriptor = TypeDescriptor.GetDescriptor(typeof(TEntity)); EnsureEntityHasPrimaryKey(typeDescriptor); MappingMemberDescriptor keyMemberDescriptor = typeDescriptor.PrimaryKey; MappingMemberDescriptor autoIncrementMemberDescriptor = typeDescriptor.AutoIncrement; Dictionary <MemberInfo, Expression> insertColumns = InitMemberExtractor.Extract(body); DbInsertExpression e = new DbInsertExpression(typeDescriptor.Table); object keyVal = null; foreach (var kv in insertColumns) { MemberInfo key = kv.Key; MappingMemberDescriptor memberDescriptor = typeDescriptor.TryGetMappingMemberDescriptor(key); if (memberDescriptor == null) { throw new ChloeException(string.Format("The member '{0}' does not map any column.", key.Name)); } if (memberDescriptor == autoIncrementMemberDescriptor) { throw new ChloeException(string.Format("Could not insert value into the identity column '{0}'.", memberDescriptor.Column.Name)); } if (memberDescriptor.IsPrimaryKey) { object val = ExpressionEvaluator.Evaluate(kv.Value); if (val == null) { throw new ChloeException(string.Format("The primary key '{0}' could not be null.", memberDescriptor.MemberInfo.Name)); } else { keyVal = val; e.InsertColumns.Add(memberDescriptor.Column, DbExpression.Parameter(keyVal)); continue; } } e.InsertColumns.Add(memberDescriptor.Column, typeDescriptor.Visitor.Visit(kv.Value)); } //主键为空并且主键又不是自增列 if (keyVal == null && keyMemberDescriptor != autoIncrementMemberDescriptor) { throw new ChloeException(string.Format("The primary key '{0}' could not be null.", keyMemberDescriptor.MemberInfo.Name)); } if (keyMemberDescriptor != autoIncrementMemberDescriptor) { this.ExecuteSqlCommand(e); return(keyVal); } IDbExpressionTranslator translator = this.DbContextServiceProvider.CreateDbExpressionTranslator(); List <DbParam> parameters; string sql = translator.Translate(e, out parameters); sql = string.Concat(sql, ";", this.GetSelectLastInsertIdClause()); //SELECT @@IDENTITY 返回的是 decimal 类型 object retIdentity = this.Session.ExecuteScalar(sql, parameters.ToArray()); if (retIdentity == null || retIdentity == DBNull.Value) { throw new ChloeException("Unable to get the identity value."); } retIdentity = ConvertIdentityType(retIdentity, autoIncrementMemberDescriptor.MemberInfoType); return(retIdentity); }
protected virtual SelectStatement GenerateReturningSql(DbModificationCommandTree tree, DbExpression returning) { SelectStatement select = base.GenerateReturningSql(tree, returning); ListFragment where = new ListFragment(); EntitySetBase table = ((DbScanExpression)tree.Target.Expression).Target; bool foundIdentity = false; where.Append(" row_count() > 0"); foreach (EdmMember keyMember in table.ElementType.KeyMembers) { SqlFragment value; if (!values.TryGetValue(keyMember, out value)) { if (foundIdentity) { throw new NotSupportedException(); } foundIdentity = true; if (keyMember.TypeUsage.EdmType.BaseType.Name.StartsWith("Int")) { value = new LiteralFragment("last_insert_id()"); } else if (keyMember.TypeUsage.EdmType.BaseType.Name == "Guid") { value = new LiteralFragment(string.Format("ANY(SELECT guid FROM tmpIdentity_{0})", (table as MetadataItem).MetadataProperties["Table"].Value)); } } where.Append(String.Format(" AND `{0}`=", keyMember)); where.Append(value); } select.Where = where; return(select); }
void BuildCastState(DbExpression castExp, string targetDbTypeString) { this.SqlBuilder.Append("CAST("); castExp.Accept(this); this.SqlBuilder.Append(" AS ", targetDbTypeString, ")"); }
public virtual TEntity Insert <TEntity>(TEntity entity) { Utils.CheckNull(entity); TypeDescriptor typeDescriptor = TypeDescriptor.GetDescriptor(entity.GetType()); EnsureEntityHasPrimaryKey(typeDescriptor); MappingMemberDescriptor keyMemberDescriptor = typeDescriptor.PrimaryKey; MemberInfo keyMember = typeDescriptor.PrimaryKey.MemberInfo; object keyValue = null; MappingMemberDescriptor autoIncrementMemberDescriptor = typeDescriptor.AutoIncrement; Dictionary <MappingMemberDescriptor, DbExpression> insertColumns = new Dictionary <MappingMemberDescriptor, DbExpression>(); foreach (var kv in typeDescriptor.MappingMemberDescriptors) { MemberInfo member = kv.Key; MappingMemberDescriptor memberDescriptor = kv.Value; if (memberDescriptor == autoIncrementMemberDescriptor) { continue; } object val = memberDescriptor.GetValue(entity); if (memberDescriptor == keyMemberDescriptor) { keyValue = val; } DbExpression valExp = DbExpression.Parameter(val, memberDescriptor.MemberInfoType); insertColumns.Add(memberDescriptor, valExp); } //主键为空并且主键又不是自增列 if (keyValue == null && keyMemberDescriptor != autoIncrementMemberDescriptor) { throw new ChloeException(string.Format("The primary key '{0}' could not be null.", keyMemberDescriptor.MemberInfo.Name)); } DbInsertExpression e = new DbInsertExpression(typeDescriptor.Table); foreach (var kv in insertColumns) { e.InsertColumns.Add(kv.Key.Column, kv.Value); } if (autoIncrementMemberDescriptor == null) { this.ExecuteSqlCommand(e); return(entity); } IDbExpressionTranslator translator = this.DbContextServiceProvider.CreateDbExpressionTranslator(); List <DbParam> parameters; string sql = translator.Translate(e, out parameters); sql = string.Concat(sql, ";", this.GetSelectLastInsertIdClause()); //SELECT @@IDENTITY 返回的是 decimal 类型 object retIdentity = this.Session.ExecuteScalar(sql, parameters.ToArray()); if (retIdentity == null || retIdentity == DBNull.Value) { throw new ChloeException("Unable to get the identity value."); } retIdentity = ConvertIdentityType(retIdentity, autoIncrementMemberDescriptor.MemberInfoType); autoIncrementMemberDescriptor.SetValue(entity, retIdentity); return(entity); }
public static DbCaseWhenExpression ConstructReturnCSharpBooleanCaseWhenExpression(DbExpression exp) { // case when 1>0 then 1 when not (1>0) then 0 else Null end DbCaseWhenExpression.WhenThenExpressionPair whenThenPair = new DbCaseWhenExpression.WhenThenExpressionPair(exp, DbConstantExpression.True); DbCaseWhenExpression.WhenThenExpressionPair whenThenPair1 = new DbCaseWhenExpression.WhenThenExpressionPair(DbExpression.Not(exp), DbConstantExpression.False); List <DbCaseWhenExpression.WhenThenExpressionPair> whenThenExps = new List <DbCaseWhenExpression.WhenThenExpressionPair>(2); whenThenExps.Add(whenThenPair); whenThenExps.Add(whenThenPair1); DbCaseWhenExpression caseWhenExpression = DbExpression.CaseWhen(whenThenExps, DbConstantExpression.Null, PublicConstants.TypeOfBoolean); return(caseWhenExpression); }
/// <summary> /// See <see cref="BoolExpression.AsCqt" />. /// </summary> internal abstract DbExpression AsCqt(DbExpression row, bool skipIsNotNull);
public static void DbFunction_DATEDIFF(SqlGeneratorBase generator, string interval, DbExpression startDateTimeExp, DbExpression endDateTimeExp) { generator.SqlBuilder.Append("DATEDIFF("); generator.SqlBuilder.Append(interval); generator.SqlBuilder.Append(","); startDateTimeExp.Accept(generator); generator.SqlBuilder.Append(","); endDateTimeExp.Accept(generator); generator.SqlBuilder.Append(")"); }
public static void DbFunction_DATEPART(SqlGeneratorBase generator, string interval, DbExpression exp) { generator.SqlBuilder.Append("DATEPART("); generator.SqlBuilder.Append(interval); generator.SqlBuilder.Append(","); exp.Accept(generator); generator.SqlBuilder.Append(")"); }
public static void Aggregate_Min(SqlGeneratorBase generator, DbExpression exp, Type retType) { AppendAggregateFunction(generator, exp, retType, "MIN", false); }
static DbExpression EnsureDbExpressionReturnCSharpBoolean(DbExpression exp) { return(DbValueExpressionTransformer.Transform(exp)); }
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); }
/// <summary> /// 创建分组并连接表达式。 /// </summary> /// <param name="source">源表达式。</param> /// <param name="target">目标表达式。</param> /// <param name="left">左端键表达式。</param> /// <param name="right">右端键表达式。</param> /// <param name="newExp">当前连接后输出的新对象表达工。</param> public DbGroupJoinExpression(DbUnitTypeExpression source, DbUnitTypeExpression target, DbExpression left, DbExpression right, DbUnitItemTypeExpression newExp) : base(source, target, left, right, newExp) { }
public Task <DbExpression> Import(DbExpression expression) { expression.Validate(); return(_expressions.Add(expression)); }
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 (DbExpressionExtension.AffirmExpressionRetValueIsNull(right) || DbExpressionExtension.AffirmExpressionRetValueIsNull(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 override void Visit(DbExpression expression) { throw new NotSupportedException("Visit(\"Expression\") is not supported."); }
internal override DbExpression AsCqt(DbExpression row, bool skipIsNotNull) { // Get e.g., row._from1 return(row.Property(SlotName)); }
public static DbExpression Transform(DbExpression exp) { return(exp.Accept(_transformer)); }
public virtual int Update <TEntity>(TEntity entity) { Utils.CheckNull(entity); TypeDescriptor typeDescriptor = TypeDescriptor.GetDescriptor(entity.GetType()); EnsureEntityHasPrimaryKey(typeDescriptor); MappingMemberDescriptor keyMemberDescriptor = typeDescriptor.PrimaryKey; MemberInfo keyMember = keyMemberDescriptor.MemberInfo; object keyVal = null; IEntityState entityState = this.TryGetTrackedEntityState(entity); Dictionary <MappingMemberDescriptor, DbExpression> updateColumns = new Dictionary <MappingMemberDescriptor, DbExpression>(); foreach (var kv in typeDescriptor.MappingMemberDescriptors) { MemberInfo member = kv.Key; MappingMemberDescriptor memberDescriptor = kv.Value; if (member == keyMember) { keyVal = memberDescriptor.GetValue(entity); keyMemberDescriptor = memberDescriptor; continue; } if (memberDescriptor.IsAutoIncrement) { continue; } var val = memberDescriptor.GetValue(entity); if (entityState != null && !entityState.HasChanged(memberDescriptor, val)) { continue; } DbExpression valExp = DbExpression.Parameter(val, memberDescriptor.MemberInfoType); updateColumns.Add(memberDescriptor, valExp); } if (keyVal == null) { throw new ChloeException(string.Format("The primary key '{0}' could not be null.", keyMember.Name)); } if (updateColumns.Count == 0) { return(0); } DbExpression left = new DbColumnAccessExpression(typeDescriptor.Table, keyMemberDescriptor.Column); DbExpression right = DbExpression.Parameter(keyVal, keyMemberDescriptor.MemberInfoType); DbExpression conditionExp = new DbEqualExpression(left, right); DbUpdateExpression e = new DbUpdateExpression(typeDescriptor.Table, conditionExp); foreach (var item in updateColumns) { e.UpdateColumns.Add(item.Key.Column, item.Value); } int ret = this.ExecuteSqlCommand(e); if (entityState != null) { entityState.Refresh(); } return(ret); }
private DbExpression AddFkRelatedEntityRefs(DbExpression viewConstructor) { // If the extent being simplified is not a C-Space entity set, or if it has already // been processed by the simplifier, then keep the original expression by returning // null. // if (doNotProcess) { return(null); } if (extent.BuiltInTypeKind != BuiltInTypeKind.EntitySet || extent.EntityContainer.DataSpace != DataSpace.CSpace) { doNotProcess = true; return(null); } // Get a reference to the entity set being simplified, and find all the foreign key // (foreign key) associations for which the association set references that entity set, // with either association end. // var targetSet = (EntitySet)extent; var relSets = targetSet.EntityContainer.BaseEntitySets .Where(es => es.BuiltInTypeKind == BuiltInTypeKind.AssociationSet) .Cast <AssociationSet>() .Where( assocSet => assocSet.ElementType.IsForeignKey && assocSet.AssociationSetEnds.Any(se => se.EntitySet == targetSet) ) .ToList(); // If no foreign key association sets that reference the entity set are present, then // no further processing is necessary, because FK-based related entity references cannot // be computed and added to the entities constructed for the entity set. if (relSets.Count == 0) { doNotProcess = true; return(null); } // For every relationship set that references this entity set, the relationship type and // foreign key constraint are used to determine if the entity set is the dependent set. // If it is the dependent set, then it is possible to augment the view definition with a // related entity ref that represents the navigation of the relationship set's relationship // from the dependent end (this entity set) to the principal end (the entity set that // is referenced by the other association set end of the relationship set). // var principalSetsAndDependentTypes = new HashSet <Tuple <EntityType, AssociationSetEnd, ReferentialConstraint> >(); foreach (var relSet in relSets) { // Retrieve the single referential constraint from the foreign key association, and // use it to determine whether the association set end that represents the dependent // end of the association references this entity set. // var fkConstraint = relSet.ElementType.ReferentialConstraints[0]; var dependentSetEnd = relSet.AssociationSetEnds[fkConstraint.ToRole.Name]; if (dependentSetEnd.EntitySet == targetSet) { var requiredSourceNavType = (EntityType)TypeHelpers.GetEdmType <RefType>(dependentSetEnd.CorrespondingAssociationEndMember.TypeUsage).ElementType; var principalSetEnd = relSet.AssociationSetEnds[fkConstraint.FromRole.Name]; // Record the entity type that an element of this dependent entity set must have in order // to be a valid navigation source for the relationship set's relationship, along with the // association set end for the destination (principal) end of the navigation and the FK // constraint that is associated with the relationship type. This information may be used // later to construct a related entity ref for any entity constructor expression in the view // that produces an entity of the required source type or a subtype. // principalSetsAndDependentTypes.Add(Tuple.Create(requiredSourceNavType, principalSetEnd, fkConstraint)); } } // If no foreign key association sets that use the entity set as the dependent set are present, // then no further processing is possible, since FK-based related entity refs can only be added // to the view definition for navigations from the dependent end of the relationship to the principal. // if (principalSetsAndDependentTypes.Count == 0) { doNotProcess = true; return(null); } // This rule supports a view that is capped with a projection of the form // (input).Project(x => new Entity()) // or // (input).Project(x => CASE WHEN (condition1) THEN new Entity1() ELSE WHEN (condition2) THEN new Entity2()... ELSE new EntityN()) // where every new instance expression Entity1()...EntityN() constructs an entity of a type // that is compatible with the entity set's element type. // Here, the list of all DbNewInstanceExpressions contained in the projection is remembered, // along with any CASE statement conditions, if present. These expressions will be updated // if necessary and used to build a new capping projection if any of the entity constructors // are augmented with FK-based related entity references. // var entityProject = (DbProjectExpression)viewConstructor; var constructors = new List <DbNewInstanceExpression>(); List <DbExpression> conditions = null; if (entityProject.Projection.ExpressionKind == DbExpressionKind.Case) { // If the projection is a DbCaseExpression, then every result must be a DbNewInstanceExpression var discriminatedConstructor = (DbCaseExpression)entityProject.Projection; conditions = new List <DbExpression>(discriminatedConstructor.When.Count); for (var idx = 0; idx < discriminatedConstructor.When.Count; idx++) { conditions.Add(discriminatedConstructor.When[idx]); constructors.Add((DbNewInstanceExpression)discriminatedConstructor.Then[idx]); } constructors.Add((DbNewInstanceExpression)discriminatedConstructor.Else); } else { // Otherwise, the projection must be a single DbNewInstanceExpression constructors.Add((DbNewInstanceExpression)entityProject.Projection); } var rebuildView = false; for (var idx = 0; idx < constructors.Count; idx++) { var entityConstructor = constructors[idx]; var constructedEntityType = TypeHelpers.GetEdmType <EntityType>(entityConstructor.ResultType); var relatedRefs = principalSetsAndDependentTypes .Where(psdt => constructedEntityType == psdt.Item1 || constructedEntityType.IsSubtypeOf(psdt.Item1)) .Select( psdt => RelatedEntityRefFromAssociationSetEnd(constructedEntityType, entityConstructor, psdt.Item2, psdt.Item3)) .ToList(); if (relatedRefs.Count > 0) { if (entityConstructor.HasRelatedEntityReferences) { relatedRefs = entityConstructor.RelatedEntityReferences.Concat(relatedRefs).ToList(); } entityConstructor = DbExpressionBuilder.CreateNewEntityWithRelationshipsExpression( constructedEntityType, entityConstructor.Arguments, relatedRefs); constructors[idx] = entityConstructor; rebuildView = true; } } // Default to returning null to indicate that this rule did not produce a modified expression // DbExpression result = null; if (rebuildView) { // rebuildView is true, so entity constructing DbNewInstanceExpression(s) were encountered // and updated with additional related entity refs. The DbProjectExpression that caps the // view definition therefore needs to be rebuilt and returned as the result of this rule. // if (conditions != null) { // The original view definition projection was a DbCaseExpression. // The new expression is also a DbCaseExpression that uses the conditions from the // original expression together with the updated result expressions to produce the // new capping projection. // var whens = new List <DbExpression>(conditions.Count); var thens = new List <DbExpression>(conditions.Count); for (var idx = 0; idx < conditions.Count; idx++) { whens.Add(conditions[idx]); thens.Add(constructors[idx]); } result = entityProject.Input.Project(DbExpressionBuilder.Case(whens, thens, constructors[conditions.Count])); } else { // Otherwise, the capping projection consists entirely of the updated DbNewInstanceExpression. // result = entityProject.Input.Project(constructors[0]); } } // Regardless of whether or not the view was updated, this rule should not be applied again during rule processing doNotProcess = true; return(result); }
/// <summary> /// Generates CQT of the form "leftSlot = rightSlot". /// </summary> internal DbExpression AsCqt(DbExpression leftRow, DbExpression rightRow) { return(m_leftSlot.AsCqt(leftRow, m_leftSlotOutputMember).Equal(m_rightSlot.AsCqt(rightRow, m_rightSlotOutputMember))); }
// Visit and identify the Property(VarRef "Outer binding") pattern, // remapping the property to the appropriate inner projection member internal DbExpression CollapseProjection(DbExpression expression) { return(VisitExpression(expression)); }
public override DbExpressionEntitySetInfo Visit(DbExpression expression) { Check.NotNull(expression, "expression"); return(null); }
private static DbExpression SimplifyNestedTphDiscriminator(DbExpression expression) { var entityProjection = (DbProjectExpression)expression; var booleanColumnFilter = (DbFilterExpression)entityProjection.Input.Expression; var rowProjection = (DbProjectExpression)booleanColumnFilter.Input.Expression; var discriminatorFilter = (DbFilterExpression)rowProjection.Input.Expression; var predicates = FlattenOr(booleanColumnFilter.Predicate).ToList(); var propertyPredicates = predicates.OfType <DbPropertyExpression>() .Where( px => px.Instance.ExpressionKind == DbExpressionKind.VariableReference && ((DbVariableReferenceExpression)px.Instance).VariableName == booleanColumnFilter.Input.VariableName) .ToList(); if (predicates.Count != propertyPredicates.Count) { return(null); } var predicateColumnNames = propertyPredicates.Select(px => px.Property.Name).ToList(); var discriminatorPredicates = new Dictionary <object, DbComparisonExpression>(); if (!TypeSemantics.IsEntityType(discriminatorFilter.Input.VariableType) || !TryMatchDiscriminatorPredicate(discriminatorFilter, (compEx, discValue) => discriminatorPredicates.Add(discValue, compEx))) { return(null); } var discriminatorProp = (EdmProperty)((DbPropertyExpression)(discriminatorPredicates.First().Value).Left).Property; var rowConstructor = (DbNewInstanceExpression)rowProjection.Projection; var resultRow = TypeHelpers.GetEdmType <RowType>(rowConstructor.ResultType); var inputPredicateMap = new Dictionary <string, DbComparisonExpression>(); var selectorPredicateMap = new Dictionary <string, DbComparisonExpression>(); var columnValues = new Dictionary <string, DbExpression>(rowConstructor.Arguments.Count); for (var idx = 0; idx < rowConstructor.Arguments.Count; idx++) { var propName = resultRow.Properties[idx].Name; var columnVal = rowConstructor.Arguments[idx]; if (predicateColumnNames.Contains(propName)) { if (columnVal.ExpressionKind != DbExpressionKind.Case) { return(null); } var casePredicate = (DbCaseExpression)columnVal; if (casePredicate.When.Count != 1 || !TypeSemantics.IsBooleanType(casePredicate.Then[0].ResultType) || !TypeSemantics.IsBooleanType(casePredicate.Else.ResultType) || casePredicate.Then[0].ExpressionKind != DbExpressionKind.Constant || casePredicate.Else.ExpressionKind != DbExpressionKind.Constant || (bool)((DbConstantExpression)casePredicate.Then[0]).Value != true || (bool)((DbConstantExpression)casePredicate.Else).Value) { return(null); } DbPropertyExpression comparedProp; object constValue; if ( !TryMatchPropertyEqualsValue( casePredicate.When[0], rowProjection.Input.VariableName, out comparedProp, out constValue) || comparedProp.Property != discriminatorProp || !discriminatorPredicates.ContainsKey(constValue)) { return(null); } inputPredicateMap.Add(propName, discriminatorPredicates[constValue]); selectorPredicateMap.Add(propName, (DbComparisonExpression)casePredicate.When[0]); } else { columnValues.Add(propName, columnVal); } } // Build a new discriminator-based filter that only includes the same rows allowed by the higher '_from0' column-based filter var newDiscriminatorPredicate = Helpers.BuildBalancedTreeInPlace( new List <DbExpression>(inputPredicateMap.Values), (left, right) => left.Or(right)); discriminatorFilter = discriminatorFilter.Input.Filter(newDiscriminatorPredicate); var entitySelector = (DbCaseExpression)entityProjection.Projection; var newWhens = new List <DbExpression>(entitySelector.When.Count); var newThens = new List <DbExpression>(entitySelector.Then.Count); for (var idx = 0; idx < entitySelector.When.Count; idx++) { var propWhen = (DbPropertyExpression)entitySelector.When[idx]; var entityThen = (DbNewInstanceExpression)entitySelector.Then[idx]; DbComparisonExpression discriminatorWhen; if (!selectorPredicateMap.TryGetValue(propWhen.Property.Name, out discriminatorWhen)) { return(null); } newWhens.Add(discriminatorWhen); var inputBoundEntityConstructor = ValueSubstituter.Substitute(entityThen, entityProjection.Input.VariableName, columnValues); newThens.Add(inputBoundEntityConstructor); } var newElse = ValueSubstituter.Substitute(entitySelector.Else, entityProjection.Input.VariableName, columnValues); var newEntitySelector = DbExpressionBuilder.Case(newWhens, newThens, newElse); DbExpression result = discriminatorFilter.BindAs(rowProjection.Input.VariableName).Project(newEntitySelector); return(result); }
public override void Visit(DbExpression e) { Check.NotNull(e, "e"); throw new NotSupportedException(Strings.Cqt_General_UnsupportedExpression(e.GetType().FullName)); }
public void AppendCondition(DbExpression condition) { this.Condition = this.Condition.And(condition); }
public void AddConstructorParameter(ParameterInfo p, DbExpression exp) { throw new NotSupportedException(); }
public MappingFieldExpression(Type type, DbExpression exp) { this._type = type; this._exp = exp; }