-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Expand file tree
/
Copy pathISaveChangesInterceptor.cs
More file actions
200 lines (189 loc) · 11.7 KB
/
ISaveChangesInterceptor.cs
File metadata and controls
200 lines (189 loc) · 11.7 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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace Microsoft.EntityFrameworkCore.Diagnostics;
/// <summary>
/// Allows interception of the <see cref="O:DbContext.SaveChanges" /> and <see cref="O:DbContext.SaveChangesAync" /> methods.
/// </summary>
/// <remarks>
/// <para>
/// SaveChanges interceptors can be used to view, change, or suppress execution of the SaveChanges call and
/// modify the result before it is returned to EF.
/// </para>
/// <para>
/// Consider inheriting from <see cref="SaveChangesInterceptor" /> if not implementing all methods.
/// </para>
/// <para>
/// Use <see cref="DbContextOptionsBuilder.AddInterceptors(Microsoft.EntityFrameworkCore.Diagnostics.IInterceptor[])" />
/// to register application interceptors.
/// </para>
/// <para>
/// Extensions can also register interceptors in the internal service provider.
/// If both injected and application interceptors are found, then the injected interceptors are run in the
/// order that they are resolved from the service provider, and then the application interceptors are run last.
/// </para>
/// <para>
/// See <see href="https://aka.ms/efcore-docs-interceptors">EF Core interceptors</see> for more information and examples.
/// </para>
/// </remarks>
public interface ISaveChangesInterceptor : IInterceptor
{
/// <summary>
/// Called at the start of <see cref="O:DbContext.SaveChanges" />.
/// </summary>
/// <param name="eventData">Contextual information about the <see cref="DbContext" /> being used.</param>
/// <param name="result">
/// Represents the current result if one exists.
/// This value will have <see cref="InterceptionResult{Int32}.HasResult" /> set to <see langword="true" /> if some previous
/// interceptor suppressed execution by calling <see cref="InterceptionResult{Int32}.SuppressWithResult" />.
/// This value is typically used as the return value for the implementation of this method.
/// </param>
/// <returns>
/// If <see cref="InterceptionResult{Int32}.HasResult" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult{Int32}.HasResult" /> is true, then EF will suppress the operation it
/// was about to perform and use <see cref="InterceptionResult{Int32}.Result" /> instead.
/// An implementation of this method for any interceptor that is not attempting to change the result
/// is to return the <paramref name="result" /> value passed in.
/// </returns>
InterceptionResult<int> SavingChanges(DbContextEventData eventData, InterceptionResult<int> result)
=> result;
/// <summary>
/// Called at the end of <see cref="O:DbContext.SaveChanges" />.
/// </summary>
/// <remarks>
/// This method is still called if an interceptor suppressed creation of a command in <see cref="SavingChanges" />.
/// In this case, <paramref name="result" /> is the result returned by <see cref="SavingChanges" />.
/// </remarks>
/// <param name="eventData">Contextual information about the <see cref="DbContext" /> being used.</param>
/// <param name="result">
/// The result of the call to <see cref="O:DbContext.SaveChanges" />.
/// This value is typically used as the return value for the implementation of this method.
/// </param>
/// <returns>
/// The result that EF will use.
/// An implementation of this method for any interceptor that is not attempting to change the result
/// is to return the <paramref name="result" /> value passed in.
/// </returns>
int SavedChanges(SaveChangesCompletedEventData eventData, int result)
=> result;
/// <summary>
/// Called when an exception has been thrown in <see cref="O:DbContext.SaveChanges" />.
/// </summary>
/// <param name="eventData">Contextual information about the failure.</param>
void SaveChangesFailed(DbContextErrorEventData eventData)
{
}
/// <summary>
/// Called at the start of <see cref="O:DbContext.SaveChangesAsync" />.
/// </summary>
/// <param name="eventData">Contextual information about the <see cref="DbContext" /> being used.</param>
/// <param name="result">
/// Represents the current result if one exists.
/// This value will have <see cref="InterceptionResult{Int32}.HasResult" /> set to <see langword="true" /> if some previous
/// interceptor suppressed execution by calling <see cref="InterceptionResult{Int32}.SuppressWithResult" />.
/// This value is typically used as the return value for the implementation of this method.
/// </param>
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>
/// If <see cref="InterceptionResult{Int32}.HasResult" /> is false, the EF will continue as normal.
/// If <see cref="InterceptionResult{Int32}.HasResult" /> is true, then EF will suppress the operation it
/// was about to perform and use <see cref="InterceptionResult{Int32}.Result" /> instead.
/// An implementation of this method for any interceptor that is not attempting to change the result
/// is to return the <paramref name="result" /> value passed in.
/// </returns>
/// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
ValueTask<InterceptionResult<int>> SavingChangesAsync(
DbContextEventData eventData,
InterceptionResult<int> result,
CancellationToken cancellationToken = default)
=> new(result);
/// <summary>
/// Called at the end of <see cref="O:DbContext.SaveChangesAsync" />.
/// </summary>
/// <remarks>
/// This method is still called if an interceptor suppressed creation of a command in <see cref="SavingChangesAsync" />.
/// In this case, <paramref name="result" /> is the result returned by <see cref="SavingChangesAsync" />.
/// </remarks>
/// <param name="eventData">Contextual information about the <see cref="DbContext" /> being used.</param>
/// <param name="result">
/// The result of the call to <see cref="O:DbContext.SaveChangesAsync" />.
/// This value is typically used as the return value for the implementation of this method.
/// </param>
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>
/// The result that EF will use.
/// An implementation of this method for any interceptor that is not attempting to change the result
/// is to return the <paramref name="result" /> value passed in.
/// </returns>
/// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
ValueTask<int> SavedChangesAsync(
SaveChangesCompletedEventData eventData,
int result,
CancellationToken cancellationToken = default)
=> new(result);
/// <summary>
/// Called when an exception has been thrown in <see cref="O:DbContext.SaveChangesAsync" />.
/// </summary>
/// <param name="eventData">Contextual information about the failure.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>A <see cref="Task" /> representing the asynchronous operation.</returns>
/// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
Task SaveChangesFailedAsync(DbContextErrorEventData eventData, CancellationToken cancellationToken = default)
=> Task.CompletedTask;
/// <summary>
/// Called when <see cref="O:DbContext.SaveChanges" /> was canceled.
/// </summary>
/// <param name="eventData">Contextual information about the failure.</param>
void SaveChangesCanceled(DbContextEventData eventData)
{
}
/// <summary>
/// Called when <see cref="O:DbContext.SaveChangesAsync" /> was canceled.
/// </summary>
/// <param name="eventData">Contextual information about the failure.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>A <see cref="Task" /> representing the asynchronous operation.</returns>
/// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
Task SaveChangesCanceledAsync(DbContextEventData eventData, CancellationToken cancellationToken = default)
=> Task.CompletedTask;
/// <summary>
/// Called immediately before EF is going to throw a <see cref="DbUpdateConcurrencyException" />.
/// </summary>
/// <param name="eventData">Contextual information about the concurrency conflict.</param>
/// <param name="result">
/// Represents the current result if one exists.
/// This value will have <see cref="InterceptionResult.IsSuppressed" /> set to <see langword="true" /> if some previous
/// interceptor suppressed execution by calling <see cref="InterceptionResult.Suppress" />.
/// This value is typically used as the return value for the implementation of this method.
/// </param>
/// <returns>
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="false" />, then EF will throw the exception.
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="true" />, then EF will not throw the exception.
/// An implementation of this method for any interceptor that is not attempting to suppress
/// setting property values must return the <paramref name="result" /> value passed in.
/// </returns>
InterceptionResult ThrowingConcurrencyException(ConcurrencyExceptionEventData eventData, InterceptionResult result)
=> result;
/// <summary>
/// Called immediately before EF is going to throw a <see cref="DbUpdateConcurrencyException" />.
/// </summary>
/// <param name="eventData">Contextual information about the concurrency conflict.</param>
/// <param name="result">
/// Represents the current result if one exists.
/// This value will have <see cref="InterceptionResult.IsSuppressed" /> set to <see langword="true" /> if some previous
/// interceptor suppressed execution by calling <see cref="InterceptionResult.Suppress" />.
/// This value is typically used as the return value for the implementation of this method.
/// </param>
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="false" />, then EF will throw the exception.
/// If <see cref="InterceptionResult.IsSuppressed" /> is <see langword="true" />, then EF will not throw the exception.
/// An implementation of this method for any interceptor that is not attempting to suppress
/// setting property values must return the <paramref name="result" /> value passed in.
/// </returns>
/// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
ValueTask<InterceptionResult> ThrowingConcurrencyExceptionAsync(
ConcurrencyExceptionEventData eventData,
InterceptionResult result,
CancellationToken cancellationToken = default)
=> new(result);
}