You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/05/29 09:30:32 UTC
[06/24] ignite git commit: IGNITE-4904 .NET: DML Delete via LINQ
IGNITE-4904 .NET: DML Delete via LINQ
This closes #2009
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/d38ca8b1
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/d38ca8b1
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/d38ca8b1
Branch: refs/heads/ignite-5075-cc
Commit: d38ca8b1004effefa5126981f434649d26db1e68
Parents: 279f35b
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Fri May 26 13:02:01 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri May 26 13:02:01 2017 +0300
----------------------------------------------------------------------
.../Cache/Query/CacheLinqTest.cs | 70 +++++++++++++++-
.../Apache.Ignite.Linq.csproj | 3 +
.../Apache.Ignite.Linq/CacheExtensions.cs | 65 +++++++++++++++
.../Impl/CacheQueryModelVisitor.cs | 60 +++++++++++--
.../Apache.Ignite.Linq/Impl/CacheQueryParser.cs | 21 ++++-
.../Impl/Dml/RemoveAllExpressionNode.cs | 88 ++++++++++++++++++++
.../Impl/Dml/RemoveAllResultOperator.cs | 61 ++++++++++++++
.../dotnet/Apache.Ignite.sln.DotSettings | 1 +
8 files changed, 359 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/d38ca8b1/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheLinqTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheLinqTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheLinqTest.cs
index cb3fece..b603d75 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheLinqTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheLinqTest.cs
@@ -37,6 +37,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
using Apache.Ignite.Core.Cache;
using Apache.Ignite.Core.Cache.Configuration;
using Apache.Ignite.Core.Cache.Query;
+ using Apache.Ignite.Core.Common;
using Apache.Ignite.Linq;
using NUnit.Framework;
@@ -1269,7 +1270,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
var cache = GetPersonCache();
// Check regular query
- var query = (ICacheQueryable) cache.AsCacheQueryable(new QueryOptions
+ var query = cache.AsCacheQueryable(new QueryOptions
{
Local = true,
PageSize = 999,
@@ -1277,7 +1278,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
Timeout = TimeSpan.FromSeconds(2.5),
ReplicatedOnly = true,
Colocated = true
- }).Where(x => x.Key > 10);
+ }).Where(x => x.Key > 10).ToCacheQueryable();
Assert.AreEqual(cache.Name, query.CacheName);
Assert.AreEqual(cache.Ignite, query.Ignite);
@@ -1325,7 +1326,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
var distrQuery = cache.AsCacheQueryable(new QueryOptions {EnableDistributedJoins = true})
.Where(x => x.Key > 10 && x.Value.Age > 20 && x.Value.Name.Contains("x"));
- query = (ICacheQueryable) distrQuery;
+ query = distrQuery.ToCacheQueryable();
Assert.IsTrue(query.GetFieldsQuery().EnableDistributedJoins);
@@ -1424,6 +1425,69 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
}
/// <summary>
+ /// Tests the RemoveAll extension.
+ /// </summary>
+ [Test]
+ public void TestRemoveAll()
+ {
+ // Use new cache to avoid touching static data.
+ var cache = Ignition.GetIgnite().CreateCache<int, Person>(new CacheConfiguration("deleteAllTest",
+ new QueryEntity(typeof(int), typeof(Person))));
+
+ Enumerable.Range(1, 10).ToList().ForEach(x => cache.Put(x, new Person(x, x.ToString())));
+
+ var queryable = cache.AsCacheQueryable();
+
+ Func<int[]> getKeys = () => cache.Select(x => x.Key).OrderBy(x => x).ToArray();
+
+ // Without predicate.
+ var res = queryable.Where(x => x.Key < 3).RemoveAll();
+ Assert.AreEqual(2, res);
+ Assert.AreEqual(Enumerable.Range(3, 8), getKeys());
+
+ // With predicate.
+ res = queryable.RemoveAll(x => x.Key < 7);
+ Assert.AreEqual(4, res);
+ Assert.AreEqual(Enumerable.Range(7, 4), getKeys());
+
+ // Subquery-style join.
+ var ids = GetPersonCache().AsCacheQueryable().Where(x => x.Key == 7).Select(x => x.Key);
+
+ res = queryable.Where(x => ids.Contains(x.Key)).RemoveAll();
+ Assert.AreEqual(1, res);
+ Assert.AreEqual(Enumerable.Range(8, 3), getKeys());
+
+ // Row number limit.
+ res = queryable.Take(2).RemoveAll();
+ Assert.AreEqual(2, res);
+ Assert.AreEqual(1, getKeys().Length);
+
+ // Unconditional.
+ queryable.RemoveAll();
+ Assert.AreEqual(0, cache.GetSize());
+
+ // Skip is not supported with DELETE.
+ var nex = Assert.Throws<NotSupportedException>(() => queryable.Skip(1).RemoveAll());
+ Assert.AreEqual(
+ "RemoveAll can not be combined with result operators (other than Take): SkipResultOperator",
+ nex.Message);
+
+ // Multiple result operators are not supported with DELETE.
+ nex = Assert.Throws<NotSupportedException>(() => queryable.Skip(1).Take(1).RemoveAll());
+ Assert.AreEqual(
+ "RemoveAll can not be combined with result operators (other than Take): SkipResultOperator, " +
+ "TakeResultOperator, RemoveAllResultOperator", nex.Message);
+
+ // Joins are not supported in H2.
+ var qry = queryable
+ .Where(x => x.Key == 7)
+ .Join(GetPersonCache().AsCacheQueryable(), p => p.Key, p => p.Key, (p1, p2) => p1);
+
+ var ex = Assert.Throws<IgniteException>(() => qry.RemoveAll());
+ Assert.AreEqual("Failed to parse query", ex.Message.Substring(0, 21));
+ }
+
+ /// <summary>
/// Gets the person cache.
/// </summary>
/// <returns></returns>
http://git-wip-us.apache.org/repos/asf/ignite/blob/d38ca8b1/modules/platforms/dotnet/Apache.Ignite.Linq/Apache.Ignite.Linq.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Apache.Ignite.Linq.csproj b/modules/platforms/dotnet/Apache.Ignite.Linq/Apache.Ignite.Linq.csproj
index a7ec402..f4949d7 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/Apache.Ignite.Linq.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Apache.Ignite.Linq.csproj
@@ -63,6 +63,8 @@
<Compile Include="Impl\CacheQueryExpressionVisitor.cs" />
<Compile Include="Impl\CacheQueryModelVisitor.cs" />
<Compile Include="Impl\CacheQueryParser.cs" />
+ <Compile Include="Impl\Dml\RemoveAllExpressionNode.cs" />
+ <Compile Include="Impl\Dml\RemoveAllResultOperator.cs" />
<Compile Include="Impl\ICacheQueryableInternal.cs" />
<Compile Include="Impl\MethodVisitor.cs" />
<Compile Include="Impl\QueryData.cs" />
@@ -83,6 +85,7 @@
<Name>Apache.Ignite.Core</Name>
</ProjectReference>
</ItemGroup>
+ <ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
http://git-wip-us.apache.org/repos/asf/ignite/blob/d38ca8b1/modules/platforms/dotnet/Apache.Ignite.Linq/CacheExtensions.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/CacheExtensions.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/CacheExtensions.cs
index 2c609c6..f759dbb 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/CacheExtensions.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/CacheExtensions.cs
@@ -17,11 +17,15 @@
namespace Apache.Ignite.Linq
{
+ using System;
+ using System.Diagnostics.CodeAnalysis;
using System.Linq;
+ using System.Linq.Expressions;
using Apache.Ignite.Core.Cache;
using Apache.Ignite.Core.Cache.Configuration;
using Apache.Ignite.Core.Impl.Common;
using Apache.Ignite.Linq.Impl;
+ using Apache.Ignite.Linq.Impl.Dml;
/// <summary>
/// Extensions methods for <see cref="ICache{TK,TV}"/>.
@@ -126,5 +130,66 @@ namespace Apache.Ignite.Linq
return new CacheQueryable<TKey, TValue>(cache, queryOptions);
}
+
+ /// <summary>
+ /// Casts this query to <see cref="ICacheQueryable"/>.
+ /// </summary>
+ public static ICacheQueryable ToCacheQueryable<T>(this IQueryable<T> query)
+ {
+ IgniteArgumentCheck.NotNull(query, "query");
+
+ return (ICacheQueryable) query;
+ }
+
+ /// <summary>
+ /// Removes all rows that are matched by the specified query.
+ /// <para />
+ /// This method results in "DELETE FROM" distributed SQL query, performing bulk delete
+ /// (as opposed to fetching all rows locally).
+ /// </summary>
+ /// <typeparam name="TKey">Key type.</typeparam>
+ /// <typeparam name="TValue">Value type.</typeparam>
+ /// <param name="query">The query.</param>
+ /// <returns>Affected row count.</returns>
+ [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods",
+ Justification = "Validation is present.")]
+ public static int RemoveAll<TKey, TValue>(this IQueryable<ICacheEntry<TKey, TValue>> query)
+ {
+ IgniteArgumentCheck.NotNull(query, "query");
+
+ var method = RemoveAllExpressionNode.RemoveAllMethodInfo.MakeGenericMethod(typeof(TKey), typeof(TValue));
+
+ return query.Provider.Execute<int>(Expression.Call(null, method, query.Expression));
+ }
+
+ /// <summary>
+ /// Deletes all rows that are matched by the specified query.
+ /// <para />
+ /// This method results in "DELETE FROM" distributed SQL query, performing bulk delete
+ /// (as opposed to fetching all rows locally).
+ /// </summary>
+ /// <typeparam name="TKey">Key type.</typeparam>
+ /// <typeparam name="TValue">Value type.</typeparam>
+ /// <param name="query">The query.</param>
+ /// <param name="predicate">The predicate.</param>
+ /// <returns>
+ /// Affected row count.
+ /// </returns>
+ [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters",
+ Justification = "Only specified type of predicate is valid.")]
+ [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods",
+ Justification = "Validation is present.")]
+ public static int RemoveAll<TKey, TValue>(this IQueryable<ICacheEntry<TKey, TValue>> query,
+ Expression<Func<ICacheEntry<TKey, TValue>, bool>> predicate)
+ {
+ IgniteArgumentCheck.NotNull(query, "query");
+ IgniteArgumentCheck.NotNull(predicate, "predicate");
+
+ var method = RemoveAllExpressionNode.RemoveAllPredicateMethodInfo
+ .MakeGenericMethod(typeof(TKey), typeof(TValue));
+
+ return query.Provider.Execute<int>(Expression.Call(null, method, query.Expression,
+ Expression.Quote(predicate)));
+ }
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/d38ca8b1/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs
index f566caa..12b9502 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs
@@ -26,6 +26,7 @@ namespace Apache.Ignite.Linq.Impl
using System.Linq;
using System.Linq.Expressions;
using System.Text;
+ using Apache.Ignite.Linq.Impl.Dml;
using Remotion.Linq;
using Remotion.Linq.Clauses;
using Remotion.Linq.Clauses.Expressions;
@@ -100,22 +101,69 @@ namespace Apache.Ignite.Linq.Impl
{
_aliases.Push();
- // SELECT
- _builder.Append("select ");
+ var hasDelete = VisitRemoveOperator(queryModel);
- // TOP 1 FLD1, FLD2
- VisitSelectors(queryModel, includeAllFields);
+ if (!hasDelete)
+ {
+ // SELECT
+ _builder.Append("select ");
+
+ // TOP 1 FLD1, FLD2
+ VisitSelectors(queryModel, includeAllFields);
+ }
// FROM ... WHERE ... JOIN ...
base.VisitQueryModel(queryModel);
- // UNION ...
- ProcessResultOperatorsEnd(queryModel);
+ if (!hasDelete)
+ {
+ // UNION ...
+ ProcessResultOperatorsEnd(queryModel);
+ }
_aliases.Pop();
}
/// <summary>
+ /// Visits the remove operator. Returns true if it is present.
+ /// </summary>
+ private bool VisitRemoveOperator(QueryModel queryModel)
+ {
+ var resultOps = queryModel.ResultOperators;
+
+ if (resultOps.LastOrDefault() is RemoveAllResultOperator)
+ {
+ _builder.Append("delete ");
+
+ if (resultOps.Count == 2)
+ {
+ var resOp = resultOps[0] as TakeResultOperator;
+
+ if (resOp == null)
+ {
+ throw new NotSupportedException(
+ "RemoveAll can not be combined with result operators (other than Take): " +
+ resultOps[0].GetType().Name);
+ }
+
+ _builder.Append("top ");
+ BuildSqlExpression(resOp.Count);
+ _builder.Append(" ");
+ }
+ else if (resultOps.Count > 2)
+ {
+ throw new NotSupportedException(
+ "RemoveAll can not be combined with result operators (other than Take): " +
+ string.Join(", ", resultOps.Select(x => x.GetType().Name)));
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /// <summary>
/// Visits the selectors.
/// </summary>
public void VisitSelectors(QueryModel queryModel, bool includeAllFields)
http://git-wip-us.apache.org/repos/asf/ignite/blob/d38ca8b1/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryParser.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryParser.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryParser.cs
index 794ef2e..17ec0a3 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryParser.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryParser.cs
@@ -18,10 +18,12 @@
namespace Apache.Ignite.Linq.Impl
{
using System.Threading;
+ using Apache.Ignite.Linq.Impl.Dml;
using Remotion.Linq.Parsing.ExpressionVisitors.Transformation;
using Remotion.Linq.Parsing.ExpressionVisitors.TreeEvaluation;
using Remotion.Linq.Parsing.Structure;
using Remotion.Linq.Parsing.Structure.ExpressionTreeProcessors;
+ using Remotion.Linq.Parsing.Structure.NodeTypeProviders;
/// <summary>
/// Cache query parser.
@@ -49,12 +51,29 @@ namespace Apache.Ignite.Linq.Impl
var proc = CreateCompoundProcessor(transformerRegistry);
- var parser = new ExpressionTreeParser(ExpressionTreeParser.CreateDefaultNodeTypeProvider(), proc);
+ var parser = new ExpressionTreeParser(CreateNodeTypeProvider(), proc);
return new QueryParser(parser);
}
/// <summary>
+ /// Creates the node type provider.
+ /// </summary>
+ private static INodeTypeProvider CreateNodeTypeProvider()
+ {
+ var methodInfoRegistry = MethodInfoBasedNodeTypeRegistry.CreateFromRelinqAssembly();
+
+ methodInfoRegistry.Register(RemoveAllExpressionNode.GetSupportedMethods(),
+ typeof(RemoveAllExpressionNode));
+
+ return new CompoundNodeTypeProvider(new INodeTypeProvider[]
+ {
+ methodInfoRegistry,
+ MethodNameBasedNodeTypeRegistry.CreateFromRelinqAssembly()
+ });
+ }
+
+ /// <summary>
/// Creates CompoundExpressionTreeProcessor.
/// </summary>
private static CompoundExpressionTreeProcessor CreateCompoundProcessor(
http://git-wip-us.apache.org/repos/asf/ignite/blob/d38ca8b1/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/Dml/RemoveAllExpressionNode.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/Dml/RemoveAllExpressionNode.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/Dml/RemoveAllExpressionNode.cs
new file mode 100644
index 0000000..53674ac
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/Dml/RemoveAllExpressionNode.cs
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Linq.Impl.Dml
+{
+ using System.Collections.Generic;
+ using System.Diagnostics.CodeAnalysis;
+ using System.Linq;
+ using System.Linq.Expressions;
+ using System.Reflection;
+ using Apache.Ignite.Core.Cache;
+ using Remotion.Linq.Clauses;
+ using Remotion.Linq.Parsing.Structure.IntermediateModel;
+
+ /// <summary>
+ /// Represents a <see cref="MethodCallExpression"/> for
+ /// <see cref="CacheLinqExtensions.RemoveAll{TKey,TValue}(IQueryable{ICacheEntry{TKey,TValue}})"/>.
+ /// When user calls RemoveAll, this node is generated.
+ /// </summary>
+ internal sealed class RemoveAllExpressionNode : ResultOperatorExpressionNodeBase
+ {
+ /** */
+ private static readonly MethodInfo[] RemoveAllMethodInfos = typeof(CacheLinqExtensions)
+ .GetMethods().Where(x => x.Name == "RemoveAll").ToArray();
+
+ /// <summary>
+ /// The RemoveAll() method.
+ /// </summary>
+ public static readonly MethodInfo RemoveAllMethodInfo =
+ RemoveAllMethodInfos.Single(x => x.GetParameters().Length == 1);
+
+ /// <summary>
+ /// The RemoveAll(pred) method.
+ /// </summary>
+ public static readonly MethodInfo RemoveAllPredicateMethodInfo =
+ RemoveAllMethodInfos.Single(x => x.GetParameters().Length == 2);
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="RemoveAllExpressionNode"/> class.
+ /// </summary>
+ /// <param name="parseInfo">The parse information.</param>
+ /// <param name="optionalPredicate">The optional predicate.</param>
+ /// <param name="optionalSelector">The optional selector.</param>
+ public RemoveAllExpressionNode(MethodCallExpressionParseInfo parseInfo,
+ LambdaExpression optionalPredicate, LambdaExpression optionalSelector)
+ : base(parseInfo, optionalPredicate, optionalSelector)
+ {
+ // No-op.
+ }
+
+ /** <inheritdoc /> */
+ [ExcludeFromCodeCoverage]
+ public override Expression Resolve(ParameterExpression inputParameter, Expression expressionToBeResolved,
+ ClauseGenerationContext clauseGenerationContext)
+ {
+ throw CreateResolveNotSupportedException();
+ }
+
+ /** <inheritdoc /> */
+ protected override ResultOperatorBase CreateResultOperator(ClauseGenerationContext clauseGenerationContext)
+ {
+ return new RemoveAllResultOperator();
+ }
+
+ /// <summary>
+ /// Gets the supported methods.
+ /// </summary>
+ public static IEnumerable<MethodInfo> GetSupportedMethods()
+ {
+ yield return RemoveAllMethodInfo;
+ yield return RemoveAllPredicateMethodInfo;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/d38ca8b1/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/Dml/RemoveAllResultOperator.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/Dml/RemoveAllResultOperator.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/Dml/RemoveAllResultOperator.cs
new file mode 100644
index 0000000..76789cb
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/Dml/RemoveAllResultOperator.cs
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Linq.Impl.Dml
+{
+ using System;
+ using System.Diagnostics.CodeAnalysis;
+ using System.Linq;
+ using System.Linq.Expressions;
+ using Apache.Ignite.Core.Cache;
+ using Remotion.Linq.Clauses;
+ using Remotion.Linq.Clauses.ResultOperators;
+ using Remotion.Linq.Clauses.StreamedData;
+
+ /// <summary>
+ /// Represents an operator for <see cref="CacheLinqExtensions.RemoveAll{TK,TV}(IQueryable{ICacheEntry{TK,TV}})"/>.
+ /// </summary>
+ internal sealed class RemoveAllResultOperator : ValueFromSequenceResultOperatorBase
+ {
+ /** <inheritdoc /> */
+ public override IStreamedDataInfo GetOutputDataInfo(IStreamedDataInfo inputInfo)
+ {
+ return new StreamedScalarValueInfo(typeof(int));
+ }
+
+ /** <inheritdoc /> */
+ [ExcludeFromCodeCoverage]
+ public override ResultOperatorBase Clone(CloneContext cloneContext)
+ {
+ return new RemoveAllResultOperator();
+ }
+
+ /** <inheritdoc /> */
+ [ExcludeFromCodeCoverage]
+ public override void TransformExpressions(Func<Expression, Expression> transformation)
+ {
+ // No-op.
+ }
+
+ /** <inheritdoc /> */
+ [ExcludeFromCodeCoverage]
+ public override StreamedValue ExecuteInMemory<T>(StreamedSequence sequence)
+ {
+ throw new NotSupportedException("RemoveAll is not supported for in-memory sequences.");
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/d38ca8b1/modules/platforms/dotnet/Apache.Ignite.sln.DotSettings
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.sln.DotSettings b/modules/platforms/dotnet/Apache.Ignite.sln.DotSettings
index 078e9fb..9d5b728 100644
--- a/modules/platforms/dotnet/Apache.Ignite.sln.DotSettings
+++ b/modules/platforms/dotnet/Apache.Ignite.sln.DotSettings
@@ -7,4 +7,5 @@
<s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/AddImportsToDeepestScope/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/QualifiedUsingAtNestedScope/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertClosureToMethodGroup/@EntryIndexedValue">DO_NOT_SHOW</s:String>
+ <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002EXml_002ECodeStyle_002EFormatSettingsUpgrade_002EXmlMoveToCommonFormatterSettingsUpgrade/@EntryIndexedValue">True</s:Boolean>
</wpf:ResourceDictionary>
\ No newline at end of file