diff --git a/src/NHibernate.Test/Async/Linq/QueryReadOnlyTests.cs b/src/NHibernate.Test/Async/Linq/QueryReadOnlyTests.cs
new file mode 100644
index 00000000000..a4f2605d0bc
--- /dev/null
+++ b/src/NHibernate.Test/Async/Linq/QueryReadOnlyTests.cs
@@ -0,0 +1,50 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by AsyncGenerator.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+
+using System.Linq;
+using NHibernate.Linq;
+using NUnit.Framework;
+
+namespace NHibernate.Test.Linq
+{
+ using System.Threading.Tasks;
+ [TestFixture]
+ public class QueryReadOnlyTestsAsync : LinqTestCase
+ {
+ [Test]
+ public async Task CanSetReadOnlyOnLinqQueriesAsync()
+ {
+ var result = await ((from e in db.Customers
+ where e.CompanyName == "Bon app'"
+ select e).WithOptions(o => o.SetReadOnly(true)).ToListAsync());
+
+ Assert.That(result.All(x => session.IsReadOnly(x)), Is.True);
+ }
+
+ [Test]
+ public async Task CanSetReadOnlyOnLinqPagingQueryAsync()
+ {
+ var result = await ((from e in db.Customers
+ select e).Skip(1).Take(1).WithOptions(o => o.SetReadOnly(true)).ToListAsync());
+
+ Assert.That(result.All(x => session.IsReadOnly(x)), Is.True);
+ }
+
+ [Test]
+ public async Task CanSetReadOnlyBeforeSkipOnLinqOrderedPageQueryAsync()
+ {
+ var result = await ((from e in db.Customers
+ orderby e.CompanyName
+ select e).WithOptions(o => o.SetReadOnly(true)).Skip(5).Take(5).ToListAsync());
+
+ Assert.That(result.All(x => session.IsReadOnly(x)), Is.True);
+ }
+ }
+}
diff --git a/src/NHibernate.Test/Linq/QueryReadOnlyTests.cs b/src/NHibernate.Test/Linq/QueryReadOnlyTests.cs
new file mode 100644
index 00000000000..6b683d9a4d0
--- /dev/null
+++ b/src/NHibernate.Test/Linq/QueryReadOnlyTests.cs
@@ -0,0 +1,39 @@
+using System.Linq;
+using NHibernate.Linq;
+using NUnit.Framework;
+
+namespace NHibernate.Test.Linq
+{
+ [TestFixture]
+ public class QueryReadOnlyTests : LinqTestCase
+ {
+ [Test]
+ public void CanSetReadOnlyOnLinqQueries()
+ {
+ var result = (from e in db.Customers
+ where e.CompanyName == "Bon app'"
+ select e).WithOptions(o => o.SetReadOnly(true)).ToList();
+
+ Assert.That(result.All(x => session.IsReadOnly(x)), Is.True);
+ }
+
+ [Test]
+ public void CanSetReadOnlyOnLinqPagingQuery()
+ {
+ var result = (from e in db.Customers
+ select e).Skip(1).Take(1).WithOptions(o => o.SetReadOnly(true)).ToList();
+
+ Assert.That(result.All(x => session.IsReadOnly(x)), Is.True);
+ }
+
+ [Test]
+ public void CanSetReadOnlyBeforeSkipOnLinqOrderedPageQuery()
+ {
+ var result = (from e in db.Customers
+ orderby e.CompanyName
+ select e).WithOptions(o => o.SetReadOnly(true)).Skip(5).Take(5).ToList();
+
+ Assert.That(result.All(x => session.IsReadOnly(x)), Is.True);
+ }
+ }
+}
diff --git a/src/NHibernate/Async/Linq/DefaultQueryProvider.cs b/src/NHibernate/Async/Linq/DefaultQueryProvider.cs
index c927dea45c3..c0e32a49cb2 100644
--- a/src/NHibernate/Async/Linq/DefaultQueryProvider.cs
+++ b/src/NHibernate/Async/Linq/DefaultQueryProvider.cs
@@ -69,7 +69,7 @@ public Task ExecuteDmlAsync(QueryMode queryMode, Expression expression,
var query = Session.CreateQuery(nhLinqExpression);
SetParameters(query, nhLinqExpression.ParameterValuesByName);
- ApplyOptions(query);
+ _options?.Apply(query);
return query.ExecuteUpdateAsync(cancellationToken);
}
catch (Exception ex)
diff --git a/src/NHibernate/Linq/DefaultQueryProvider.cs b/src/NHibernate/Linq/DefaultQueryProvider.cs
index aacaa9357f8..d43ae5568c4 100644
--- a/src/NHibernate/Linq/DefaultQueryProvider.cs
+++ b/src/NHibernate/Linq/DefaultQueryProvider.cs
@@ -175,30 +175,12 @@ protected virtual NhLinqExpression PrepareQuery(Expression expression, out IQuer
}
SetParameters(query, nhLinqExpression.ParameterValuesByName);
- ApplyOptions(query);
+ _options?.Apply(query);
SetResultTransformerAndAdditionalCriteria(query, nhLinqExpression, nhLinqExpression.ParameterValuesByName);
return nhLinqExpression;
}
- private void ApplyOptions(IQuery query)
- {
- if (_options == null)
- return;
-
- if (_options.Timeout.HasValue)
- query.SetTimeout(_options.Timeout.Value);
-
- if (_options.Cacheable.HasValue)
- query.SetCacheable(_options.Cacheable.Value);
-
- if (_options.CacheMode.HasValue)
- query.SetCacheMode(_options.CacheMode.Value);
-
- if (_options.CacheRegion != null)
- query.SetCacheRegion(_options.CacheRegion);
- }
-
protected virtual object ExecuteQuery(NhLinqExpression nhLinqExpression, IQuery query, NhLinqExpression nhQuery)
{
IList results = query.List();
@@ -279,7 +261,7 @@ public int ExecuteDml(QueryMode queryMode, Expression expression)
var query = Session.CreateQuery(nhLinqExpression);
SetParameters(query, nhLinqExpression.ParameterValuesByName);
- ApplyOptions(query);
+ _options?.Apply(query);
return query.ExecuteUpdate();
}
}
diff --git a/src/NHibernate/Linq/IQueryableOptions.cs b/src/NHibernate/Linq/IQueryableOptions.cs
index 45ca5665194..0cff31e2f38 100644
--- a/src/NHibernate/Linq/IQueryableOptions.cs
+++ b/src/NHibernate/Linq/IQueryableOptions.cs
@@ -1,9 +1,13 @@
+using System;
+
namespace NHibernate.Linq
{
// Methods signatures taken from IQuery.
///
/// Expose NH queryable options.
///
+ //Since v5.1
+ [Obsolete("Please use NhQueryableOptions instead.")]
public interface IQueryableOptions
{
///
@@ -29,7 +33,7 @@ public interface IQueryableOptions
IQueryableOptions SetCacheMode(CacheMode cacheMode);
///
- /// The timeout for the underlying ADO query.
+ /// Set the timeout for the underlying ADO query.
///
/// The timeout in seconds.
/// (for method chaining).
diff --git a/src/NHibernate/Linq/NhQueryableOptions.cs b/src/NHibernate/Linq/NhQueryableOptions.cs
index 3a584ced977..4d68636386b 100644
--- a/src/NHibernate/Linq/NhQueryableOptions.cs
+++ b/src/NHibernate/Linq/NhQueryableOptions.cs
@@ -1,45 +1,134 @@
namespace NHibernate.Linq
{
- public class NhQueryableOptions: IQueryableOptions
+ ///
+ /// Expose NH queryable options.
+ ///
+ public class NhQueryableOptions
+#pragma warning disable 618
+ : IQueryableOptions
+#pragma warning restore 618
{
- protected internal bool? Cacheable { get; private set; }
- protected internal CacheMode? CacheMode{ get; private set; }
- protected internal string CacheRegion { get; private set; }
- protected internal int? Timeout { get; private set; }
+ protected bool? Cacheable { get; private set; }
+ protected CacheMode? CacheMode { get; private set; }
+ protected string CacheRegion { get; private set; }
+ protected int? Timeout { get; private set; }
+ protected bool? ReadOnly { get; private set; }
- public IQueryableOptions SetCacheable(bool cacheable)
+#pragma warning disable 618
+ ///
+ IQueryableOptions IQueryableOptions.SetCacheable(bool cacheable) => SetCacheable(cacheable);
+
+ ///
+ IQueryableOptions IQueryableOptions.SetCacheMode(CacheMode cacheMode) => SetCacheMode(cacheMode);
+
+ ///
+ IQueryableOptions IQueryableOptions.SetCacheRegion(string cacheRegion) => SetCacheRegion(cacheRegion);
+
+ ///
+ IQueryableOptions IQueryableOptions.SetTimeout(int timeout) => SetTimeout(timeout);
+#pragma warning restore 618
+
+ ///
+ /// Enable caching of this query result set.
+ ///
+ /// Should the query results be cacheable?
+ /// (for method chaining).
+ public NhQueryableOptions SetCacheable(bool cacheable)
{
Cacheable = cacheable;
return this;
}
- public IQueryableOptions SetCacheMode(CacheMode cacheMode)
+ ///
+ /// Override the current session cache mode, just for this query.
+ ///
+ /// The cache mode to use.
+ /// (for method chaining).
+ public NhQueryableOptions SetCacheMode(CacheMode cacheMode)
{
CacheMode = cacheMode;
return this;
}
- public IQueryableOptions SetCacheRegion(string cacheRegion)
+ ///
+ /// Set the name of the cache region.
+ ///
+ /// The name of a query cache region, or
+ /// for the default query cache
+ /// (for method chaining).
+ public NhQueryableOptions SetCacheRegion(string cacheRegion)
{
CacheRegion = cacheRegion;
return this;
}
- public IQueryableOptions SetTimeout(int timeout)
+ ///
+ /// Set the timeout for the underlying ADO query.
+ ///
+ /// The timeout in seconds.
+ /// (for method chaining).
+ public NhQueryableOptions SetTimeout(int timeout)
{
Timeout = timeout;
return this;
}
- internal NhQueryableOptions Clone()
+ ///
+ /// Set the read-only mode for entities (and proxies) loaded by this query. This setting
+ /// overrides the default setting for the session (see ).
+ ///
+ ///
+ ///
+ /// Read-only entities can be modified, but changes are not persisted. They are not
+ /// dirty-checked and snapshots of persistent state are not maintained.
+ ///
+ ///
+ /// When a proxy is initialized, the loaded entity will have the same read-only setting
+ /// as the uninitialized proxy, regardless of the session's current setting.
+ ///
+ ///
+ /// The read-only setting has no impact on entities or proxies returned by the criteria
+ /// that existed in the session before the criteria was executed.
+ ///
+ ///
+ ///
+ /// If true, entities (and proxies) loaded by the query will be read-only.
+ ///
+ /// this (for method chaining)
+ public NhQueryableOptions SetReadOnly(bool readOnly)
+ {
+ ReadOnly = readOnly;
+ return this;
+ }
+
+ protected internal NhQueryableOptions Clone()
{
return new NhQueryableOptions
{
Cacheable = Cacheable,
CacheMode = CacheMode,
CacheRegion = CacheRegion,
- Timeout = Timeout
+ Timeout = Timeout,
+ ReadOnly = ReadOnly
};
}
+
+ protected internal void Apply(IQuery query)
+ {
+ if (Timeout.HasValue)
+ query.SetTimeout(Timeout.Value);
+
+ if (Cacheable.HasValue)
+ query.SetCacheable(Cacheable.Value);
+
+ if (CacheMode.HasValue)
+ query.SetCacheMode(CacheMode.Value);
+
+ if (CacheRegion != null)
+ query.SetCacheRegion(CacheRegion);
+
+ if (ReadOnly.HasValue)
+ query.SetReadOnly(ReadOnly.Value);
+ }
}
}