Skip to content

Commit

Permalink
Fix query cache miss for Set(value)/Value(value)-based queries over n…
Browse files Browse the repository at this point in the history
…ullable<T> columns (#3283)

* add benchmark

* update benchmarks and tests

* Removed unnecessary convert logic.

Co-authored-by: Svyatoslav Danyliv <sdanyliv@gmail.com>
  • Loading branch information
MaceWindu and sdanyliv committed Oct 22, 2021
1 parent 015c1af commit 18d9f51
Show file tree
Hide file tree
Showing 5 changed files with 645 additions and 56 deletions.
22 changes: 5 additions & 17 deletions Source/LinqToDB/LinqExtensions.cs
Expand Up @@ -788,7 +788,7 @@ public static IUpdatable<T> AsUpdatable<T>(this IQueryable<T> source)
Expression.Call(
null,
Methods.LinqToDB.Update.SetQueryableValue.MakeGenericMethod(typeof(T), typeof(TV)),
currentSource.Expression, Expression.Quote(extract), WrapConstant(extract.Body, value)));
currentSource.Expression, Expression.Quote(extract), Expression.Constant(value, typeof(TV))));

return new Updatable<T>(query);
}
Expand Down Expand Up @@ -818,7 +818,7 @@ public static IUpdatable<T> AsUpdatable<T>(this IQueryable<T> source)
Expression.Call(
null,
Methods.LinqToDB.Update.SetUpdatableValue.MakeGenericMethod(typeof(T), typeof(TV)),
query.Expression, Expression.Quote(extract), WrapConstant(extract.Body, value)));
query.Expression, Expression.Quote(extract), Expression.Constant(value, typeof(TV))));

return new Updatable<T>(query);
}
Expand Down Expand Up @@ -1210,7 +1210,7 @@ public static IValueInsertable<T> Into<T>(this IDataContext dataContext, ITable<
Expression.Call(
null,
MethodHelper.GetMethodInfo(Value, source, field, value),
query.Expression, Expression.Quote(field), WrapConstant(field.Body, value)));
query.Expression, Expression.Quote(field), Expression.Constant(value, typeof(TV))));

return new ValueInsertable<T>(q);
}
Expand Down Expand Up @@ -1271,7 +1271,7 @@ public static IValueInsertable<T> Into<T>(this IDataContext dataContext, ITable<
Expression.Call(
null,
MethodHelper.GetMethodInfo(Value, source, field, value),
query.Expression, Expression.Quote(field), WrapConstant(field.Body, value)));
query.Expression, Expression.Quote(field), Expression.Constant(value, typeof(TV))));

return new ValueInsertable<T>(q);
}
Expand Down Expand Up @@ -1769,18 +1769,6 @@ public override string ToString()
}
}

static Expression WrapConstant<TV>(Expression body, TV value)
{
var bodyType = body.Unwrap().Type;
var valueType = ReferenceEquals(null, value) ? bodyType : value.GetType();
if (bodyType.IsInterface)
valueType = bodyType;
var result = (Expression)Expression.Constant(value, valueType);
if (result.Type != typeof(TV))
result = Expression.Convert(result, typeof(TV));
return result;
}

/// <summary>
/// Converts LINQ query into insert query with source query data as data to insert.
/// </summary>
Expand Down Expand Up @@ -1900,7 +1888,7 @@ static Expression WrapConstant<TV>(Expression body, TV value)
Expression.Call(
null,
MethodHelper.GetMethodInfo(Value, source, field, value),
query.Expression, Expression.Quote(field), WrapConstant(field.Body, value)));
query.Expression, Expression.Quote(field), Expression.Constant(value, typeof(TValue))));

return new SelectInsertable<TSource,TTarget>(q);
}
Expand Down

0 comments on commit 18d9f51

Please sign in to comment.