-
Notifications
You must be signed in to change notification settings - Fork 934
/
Copy pathDmlExtensionMethods.cs
146 lines (135 loc) · 8.31 KB
/
DmlExtensionMethods.cs
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
using System;
using System.Linq;
using System.Linq.Expressions;
namespace NHibernate.Linq
{
/// <summary>
/// NHibernate LINQ DML extension methods. They are meant to work with <see cref="NhQueryable{T}"/>. Supplied <see cref="IQueryable{T}"/> parameters
/// should at least have an <see cref="INhQueryProvider"/> <see cref="IQueryable.Provider"/>. <see cref="ISession.Query{T}()"/> and
/// its overloads supply such queryables.
/// </summary>
public static partial class DmlExtensionMethods
{
/// <summary>
/// Delete all entities selected by the specified query. The delete operation is performed in the database without reading the entities out of it.
/// </summary>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <param name="source">The query matching the entities to delete.</param>
/// <returns>The number of deleted entities.</returns>
public static int Delete<TSource>(this IQueryable<TSource> source)
{
var provider = source.GetNhProvider();
return provider.ExecuteDml<TSource>(QueryMode.Delete, source.Expression);
}
/// <summary>
/// Update all entities selected by the specified query. The update operation is performed in the database without reading the entities out of it.
/// </summary>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <param name="source">The query matching the entities to update.</param>
/// <param name="expression">The update setters expressed as a member initialization of updated entities, e.g.
/// <c>x => new Dog { Name = x.Name, Age = x.Age + 5 }</c>. Unset members are ignored and left untouched.</param>
/// <returns>The number of updated entities.</returns>
public static int Update<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, TSource>> expression)
{
return ExecuteUpdate(source, DmlExpressionRewriter.PrepareExpression(source.Expression, expression), false);
}
/// <summary>
/// Update all entities selected by the specified query, using an anonymous initializer for specifying setters. The update operation is performed
/// in the database without reading the entities out of it.
/// </summary>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <param name="source">The query matching the entities to update.</param>
/// <param name="expression">The assignments expressed as an anonymous object, e.g.
/// <c>x => new { Name = x.Name, Age = x.Age + 5 }</c>. Unset members are ignored and left untouched.</param>
/// <returns>The number of updated entities.</returns>
public static int Update<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, object>> expression)
{
return ExecuteUpdate(source, DmlExpressionRewriter.PrepareExpressionFromAnonymous(source.Expression, expression), false);
}
/// <summary>
/// Perform an <c>update versioned</c> on all entities selected by the specified query. The update operation is performed in the database without
/// reading the entities out of it.
/// </summary>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <param name="source">The query matching the entities to update.</param>
/// <param name="expression">The update setters expressed as a member initialization of updated entities, e.g.
/// <c>x => new Dog { Name = x.Name, Age = x.Age + 5 }</c>. Unset members are ignored and left untouched.</param>
/// <returns>The number of updated entities.</returns>
public static int UpdateVersioned<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, TSource>> expression)
{
return ExecuteUpdate(source, DmlExpressionRewriter.PrepareExpression(source.Expression, expression), true);
}
/// <summary>
/// Perform an <c>update versioned</c> on all entities selected by the specified query, using an anonymous initializer for specifying setters.
/// The update operation is performed in the database without reading the entities out of it.
/// </summary>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <param name="source">The query matching the entities to update.</param>
/// <param name="expression">The assignments expressed as an anonymous object, e.g.
/// <c>x => new { Name = x.Name, Age = x.Age + 5 }</c>. Unset members are ignored and left untouched.</param>
/// <returns>The number of updated entities.</returns>
public static int UpdateVersioned<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, object>> expression)
{
return ExecuteUpdate(source, DmlExpressionRewriter.PrepareExpressionFromAnonymous(source.Expression, expression), true);
}
/// <summary>
/// Initiate an update for the entities selected by the query. Return
/// a builder allowing to set properties and allowing to execute the update.
/// </summary>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <param name="source">The query matching the entities to update.</param>
/// <returns>An update builder.</returns>
public static UpdateBuilder<TSource> UpdateBuilder<TSource>(this IQueryable<TSource> source)
{
return new UpdateBuilder<TSource>(source);
}
internal static int ExecuteUpdate<TSource>(this IQueryable<TSource> source, Expression updateExpression, bool versioned)
{
var provider = source.GetNhProvider();
return provider.ExecuteDml<TSource>(versioned ? QueryMode.UpdateVersioned : QueryMode.Update, updateExpression);
}
/// <summary>
/// Insert all entities selected by the specified query. The insert operation is performed in the database without reading the entities out of it.
/// </summary>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <typeparam name="TTarget">The type of the entities to insert.</typeparam>
/// <param name="source">The query matching entities source of the data to insert.</param>
/// <param name="expression">The expression projecting a source entity to the entity to insert.</param>
/// <returns>The number of inserted entities.</returns>
public static int InsertInto<TSource, TTarget>(this IQueryable<TSource> source, Expression<Func<TSource, TTarget>> expression)
{
return ExecuteInsert<TSource, TTarget>(source, DmlExpressionRewriter.PrepareExpression(source.Expression, expression));
}
/// <summary>
/// Insert all entities selected by the specified query, using an anonymous initializer for specifying setters. <typeparamref name="TTarget"/>
/// must be explicitly provided, e.g. <c>source.InsertInto<Cat, Dog>(c => new {...})</c>. The insert operation is performed in the
/// database without reading the entities out of it.
/// </summary>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <typeparam name="TTarget">The type of the entities to insert. Must be explicitly provided.</typeparam>
/// <param name="source">The query matching entities source of the data to insert.</param>
/// <param name="expression">The expression projecting a source entity to an anonymous object representing
/// the entity to insert.</param>
/// <returns>The number of inserted entities.</returns>
public static int InsertInto<TSource, TTarget>(this IQueryable<TSource> source, Expression<Func<TSource, object>> expression)
{
return ExecuteInsert<TSource, TTarget>(source, DmlExpressionRewriter.PrepareExpressionFromAnonymous(source.Expression, expression));
}
/// <summary>
/// Initiate an insert using selected entities as a source. Return
/// a builder allowing to set properties to insert and allowing to execute the update.
/// </summary>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <param name="source">The query matching the entities to update.</param>
/// <returns>An update builder.</returns>
public static InsertBuilder<TSource> InsertBuilder<TSource>(this IQueryable<TSource> source)
{
return new InsertBuilder<TSource>(source);
}
internal static int ExecuteInsert<TSource, TTarget>(this IQueryable<TSource> source, Expression insertExpression)
{
var provider = source.GetNhProvider();
return provider.ExecuteDml<TTarget>(QueryMode.Insert, insertExpression);
}
}
}