forked from dotnet/efcore
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathQueryContext.cs
More file actions
176 lines (154 loc) · 7.52 KB
/
Copy pathQueryContext.cs
File metadata and controls
176 lines (154 loc) · 7.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Query.Internal;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Utilities;
#nullable enable
namespace Microsoft.EntityFrameworkCore.Query
{
/// <summary>
/// <para>
/// The principal data structure used by a compiled query during execution.
/// </para>
/// <para>
/// This type is typically used by database providers (and other extensions). It is generally
/// not used in application code.
/// </para>
/// </summary>
public abstract class QueryContext : IParameterValues
{
private readonly IDictionary<string, object?> _parameterValues = new Dictionary<string, object?>();
private IStateManager? _stateManager;
/// <summary>
/// <para>
/// Creates a new <see cref="QueryContext" /> instance.
/// </para>
/// <para>
/// This type is typically used by database providers (and other extensions). It is generally
/// not used in application code.
/// </para>
/// </summary>
/// <param name="dependencies"> The dependencies to use. </param>
protected QueryContext(
[NotNull] QueryContextDependencies dependencies)
{
Check.NotNull(dependencies, nameof(dependencies));
Dependencies = dependencies;
}
/// <summary>
/// The current DbContext in using while executing the query.
/// </summary>
public virtual DbContext Context
=> Dependencies.CurrentContext.Context;
/// <summary>
/// Parameter object containing dependencies for this service.
/// </summary>
protected virtual QueryContextDependencies Dependencies { get; }
/// <summary>
/// Sets the navigation for given entity as loaded.
/// </summary>
/// <param name="entity"> The entity instance. </param>
/// <param name="navigation"> The navigation property. </param>
public virtual void SetNavigationIsLoaded([NotNull] object entity, [NotNull] INavigationBase navigation)
{
Check.NotNull(entity, nameof(entity));
Check.NotNull(navigation, nameof(navigation));
// InitializeStateManager will populate the field before calling here
_stateManager!.TryGetEntry(entity).SetIsLoaded(navigation);
}
/// <summary>
/// The query provider.
/// </summary>
[Obsolete("The service requiring IQueryProvider should inject it directly.")]
public virtual IQueryProvider QueryProvider
=> Dependencies.QueryProvider;
/// <summary>
/// The execution strategy factory to use while executing the query.
/// </summary>
public virtual IExecutionStrategyFactory ExecutionStrategyFactory
=> Dependencies.ExecutionStrategyFactory;
/// <summary>
/// The concurrency detector to use while executing the query.
/// </summary>
public virtual IConcurrencyDetector ConcurrencyDetector
=> Dependencies.ConcurrencyDetector;
/// <summary>
/// The cancellation token to use while executing the query.
/// </summary>
public virtual CancellationToken CancellationToken { get; set; }
/// <summary>
/// The command logger to use while executing the query.
/// </summary>
public virtual IDiagnosticsLogger<DbLoggerCategory.Database.Command> CommandLogger
=> Dependencies.CommandLogger;
/// <summary>
/// The query logger to use while executing the query.
/// </summary>
public virtual IDiagnosticsLogger<DbLoggerCategory.Query> QueryLogger
=> Dependencies.QueryLogger;
/// <summary>
/// The parameter values to use while executing the query.
/// </summary>
public virtual IReadOnlyDictionary<string, object?> ParameterValues
=> (IReadOnlyDictionary<string, object?>)_parameterValues;
/// <summary>
/// Adds a parameter to <see cref="ParameterValues" /> for this query.
/// </summary>
/// <param name="name"> The name. </param>
/// <param name="value"> The value. </param>
public virtual void AddParameter(string name, object? value)
{
Check.NotEmpty(name, nameof(name));
_parameterValues.Add(name, value);
}
/// <summary>
/// Initializes the <see cref="IStateManager" /> to be used with this QueryContext.
/// </summary>
/// <param name="standAlone"> Whether a stand-alone <see cref="IStateManager" /> should be created to perform identity resolution. </param>
public virtual void InitializeStateManager(bool standAlone = false)
{
Check.DebugAssert(
_stateManager == null,
"The 'InitializeStateManager' method has been called multiple times on the current query context. This method is intended to be called only once before query enumeration starts.");
_stateManager = standAlone
? new StateManager(Dependencies.StateManager.Dependencies)
: Dependencies.StateManager;
}
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
[EntityFrameworkInternal]
public virtual InternalEntityEntry TryGetEntry(
[NotNull] IKey key,
[NotNull] object[] keyValues,
bool throwOnNullKey,
out bool hasNullKey)
// InitializeStateManager will populate the field before calling here
=> _stateManager!.TryGetEntry(key, keyValues, throwOnNullKey, out hasNullKey);
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
[EntityFrameworkInternal]
public virtual InternalEntityEntry StartTracking(
[NotNull] IEntityType entityType,
[NotNull] object entity,
ValueBuffer valueBuffer)
// InitializeStateManager will populate the field before calling here
=> _stateManager!.StartTrackingFromQuery(entityType, entity, valueBuffer);
}
}