Skip to content
This repository was archived by the owner on Feb 1, 2025. It is now read-only.

Commit 5c0ed2f

Browse files
authored
Merge pull request #233 from linq2db/version2
Version 2.6.0
2 parents 2efc6a9 + 866f7da commit 5c0ed2f

File tree

15 files changed

+117
-107
lines changed

15 files changed

+117
-107
lines changed

Build/linq2db.Default.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<Project>
22
<PropertyGroup>
3-
<Version>2.5.0</Version>
3+
<Version>2.6.0</Version>
44

55
<Authors>Svyatoslav Danyliv, Igor Tkachev, Dmitry Lukashenko, Ilya Chudin</Authors>
66
<Product>Linq to DB</Product>
77
<Company>linq2db.net</Company>
8-
<Copyright>2002-2021 linq2db.net</Copyright>
8+
<Copyright>2002-2022 linq2db.net</Copyright>
99
<RepositoryUrl>https://github.com/linq2db/linq2db.EntityFrameworkCore</RepositoryUrl>
1010
<RepositoryType>git</RepositoryType>
1111

Directory.Packages.props

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<Project>
22
<ItemGroup>
3-
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
4-
<PackageVersion Include="NUnit3TestAdapter" Version="4.0.0" />
5-
<PackageVersion Include="NUnit" Version="3.13.2" />
6-
<PackageVersion Include="FluentAssertions" Version="5.10.3" />
3+
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
4+
<PackageVersion Include="NUnit3TestAdapter" Version="4.2.1" />
5+
<PackageVersion Include="NUnit" Version="3.13.3" />
6+
<PackageVersion Include="FluentAssertions" Version="6.6.0" />
77

8-
<PackageVersion Include="linq2db" Version="3.7.0" />
9-
<PackageVersion Include="linq2db.Tools" Version="3.7.0" />
8+
<PackageVersion Include="linq2db" Version="4.0.1" />
9+
<PackageVersion Include="linq2db.Tools" Version="4.0.1" />
1010

1111
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
1212
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="6.0.0" />

NuGet/linq2db.EntityFrameworkCore.nuspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<dependencies>
1717
<group targetFramework=".NETStandard2.0">
1818
<dependency id="Microsoft.EntityFrameworkCore.Relational" version="2.2.6" />
19-
<dependency id="linq2db" version="3.7.0" />
19+
<dependency id="linq2db" version="4.0.1" />
2020
</group>
2121
</dependencies>
2222
</metadata>

Source/LinqToDB.EntityFrameworkCore/EFCoreMetadataReader.cs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,12 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru
226226
.Any(a =>
227227
{
228228
if (a.Name.EndsWith(":ValueGenerationStrategy"))
229-
return a.Value?.ToString().Contains("Identity") == true;
229+
{
230+
var value = a.Value?.ToString();
231+
232+
if (value != null && (value.Contains("Identity") || value.Contains("Serial")))
233+
return true;
234+
};
230235

231236
if (a.Name.EndsWith(":Autoincrement"))
232237
return a.Value is bool b && b;
@@ -259,6 +264,17 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru
259264
}
260265
}
261266

267+
var behaviour = prop.BeforeSaveBehavior;
268+
var skipOnInsert = prop.ValueGenerated.HasFlag(ValueGenerated.OnAdd);
269+
270+
if (skipOnInsert)
271+
{
272+
skipOnInsert = isIdentity || behaviour != PropertySaveBehavior.Save;
273+
}
274+
275+
var skipOnUpdate = behaviour != PropertySaveBehavior.Save ||
276+
prop.ValueGenerated.HasFlag(ValueGenerated.OnUpdate);
277+
262278
return new T[]
263279
{
264280
(T)(Attribute)new ColumnAttribute
@@ -271,7 +287,9 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru
271287
IsPrimaryKey = isPrimaryKey,
272288
PrimaryKeyOrder = primaryKeyOrder,
273289
IsIdentity = isIdentity,
274-
IsDiscriminator = discriminator == prop
290+
IsDiscriminator = discriminator == prop,
291+
SkipOnInsert = skipOnInsert,
292+
SkipOnUpdate = skipOnUpdate
275293
}
276294
};
277295
}
@@ -555,7 +573,7 @@ string PrepareExpressionText(Expression? expr)
555573
if (expr is SqlFunctionExpression sqlFunction)
556574
{
557575
var text = sqlFunction.FunctionName;
558-
if (!sqlFunction.Schema.IsNullOrEmpty())
576+
if (!string.IsNullOrEmpty(sqlFunction.Schema))
559577
text = sqlFunction.Schema + "." + sqlFunction.FunctionName;
560578

561579
if (!sqlFunction.IsNiladic)

Source/LinqToDB.EntityFrameworkCore/LinqToDBExtensionsAdapter.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -189,30 +189,30 @@ public Task<long> LongCountAsync<TSource>(
189189
=> EntityFrameworkQueryableExtensions.LongCountAsync(source, predicate, token);
190190

191191
/// <inheritdoc cref="EntityFrameworkQueryableExtensions.MinAsync{TSource}(IQueryable{TSource}, CancellationToken)"/>
192-
public Task<TSource> MinAsync<TSource>(
192+
public Task<TSource?> MinAsync<TSource>(
193193
IQueryable<TSource> source,
194194
CancellationToken token)
195-
=> EntityFrameworkQueryableExtensions.MinAsync(source, token);
195+
=> EntityFrameworkQueryableExtensions.MinAsync(source, token)!;
196196

197197
/// <inheritdoc cref="EntityFrameworkQueryableExtensions.MinAsync{TSource, TResult}(IQueryable{TSource}, Expression{Func{TSource, TResult}}, CancellationToken)"/>
198-
public Task<TResult> MinAsync<TSource,TResult>(
198+
public Task<TResult?> MinAsync<TSource,TResult>(
199199
IQueryable<TSource> source,
200200
Expression<Func<TSource,TResult>> selector,
201201
CancellationToken token)
202-
=> EntityFrameworkQueryableExtensions.MinAsync(source, selector, token);
202+
=> EntityFrameworkQueryableExtensions.MinAsync(source, selector, token)!;
203203

204204
/// <inheritdoc cref="EntityFrameworkQueryableExtensions.MaxAsync{TSource}(IQueryable{TSource}, CancellationToken)"/>
205-
public Task<TSource> MaxAsync<TSource>(
205+
public Task<TSource?> MaxAsync<TSource>(
206206
IQueryable<TSource> source,
207207
CancellationToken token)
208-
=> EntityFrameworkQueryableExtensions.MaxAsync(source, token);
208+
=> EntityFrameworkQueryableExtensions.MaxAsync(source, token)!;
209209

210210
/// <inheritdoc cref="EntityFrameworkQueryableExtensions.MaxAsync{TSource, TResult}(IQueryable{TSource}, Expression{Func{TSource, TResult}}, CancellationToken)"/>
211-
public Task<TResult> MaxAsync<TSource,TResult>(
211+
public Task<TResult?> MaxAsync<TSource,TResult>(
212212
IQueryable<TSource> source,
213213
Expression<Func<TSource,TResult>> selector,
214214
CancellationToken token)
215-
=> EntityFrameworkQueryableExtensions.MaxAsync(source, selector, token);
215+
=> EntityFrameworkQueryableExtensions.MaxAsync(source, selector, token)!;
216216

217217
#region SumAsync
218218

Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFExtensions.Async.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,26 +168,26 @@ public static Task<long> LongCountAsyncLinqToDB<TSource>(
168168
=> AsyncExtensions.LongCountAsync(source.ToLinqToDB(), predicate, token);
169169

170170
/// <inheritdoc cref="AsyncExtensions.MinAsync{TSource}(IQueryable{TSource}, CancellationToken)"/>
171-
public static Task<TSource> MinAsyncLinqToDB<TSource>(
171+
public static Task<TSource?> MinAsyncLinqToDB<TSource>(
172172
this IQueryable<TSource> source,
173173
CancellationToken token = default)
174174
=> AsyncExtensions.MinAsync(source.ToLinqToDB(), token);
175175

176176
/// <inheritdoc cref="AsyncExtensions.MinAsync{TSource, TResult}(IQueryable{TSource}, Expression{Func{TSource, TResult}}, CancellationToken)"/>
177-
public static Task<TResult> MinAsyncLinqToDB<TSource,TResult>(
177+
public static Task<TResult?> MinAsyncLinqToDB<TSource,TResult>(
178178
this IQueryable<TSource> source,
179179
Expression<Func<TSource,TResult>> selector,
180180
CancellationToken token = default)
181181
=> AsyncExtensions.MinAsync(source.ToLinqToDB(), selector, token);
182182

183183
/// <inheritdoc cref="AsyncExtensions.MaxAsync{TSource}(IQueryable{TSource}, CancellationToken)"/>
184-
public static Task<TSource> MaxAsyncLinqToDB<TSource>(
184+
public static Task<TSource?> MaxAsyncLinqToDB<TSource>(
185185
this IQueryable<TSource> source,
186186
CancellationToken token = default)
187187
=> AsyncExtensions.MaxAsync(source.ToLinqToDB(), token);
188188

189189
/// <inheritdoc cref="AsyncExtensions.MaxAsync{TSource, TResult}(IQueryable{TSource}, Expression{Func{TSource, TResult}}, CancellationToken)"/>
190-
public static Task<TResult> MaxAsyncLinqToDB<TSource,TResult>(
190+
public static Task<TResult?> MaxAsyncLinqToDB<TSource,TResult>(
191191
this IQueryable<TSource> source,
192192
Expression<Func<TSource,TResult>> selector,
193193
CancellationToken token = default)

Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFTools.Mapping.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,6 @@ static void InitializeSqlServerMapping()
9494
}
9595
}
9696

97-
#endregion
97+
#endregion
9898
}
9999
}

Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFToolsDataConnection.cs

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ namespace LinqToDB.EntityFrameworkCore
1919
using DataProvider;
2020
using Linq;
2121
using Expressions;
22+
using LinqToDB.Interceptors;
23+
using System.Data.Common;
2224

2325
/// <summary>
2426
/// linq2db EF.Core data connection.
2527
/// </summary>
26-
public class LinqToDBForEFToolsDataConnection : DataConnection, IExpressionPreprocessor
28+
public class LinqToDBForEFToolsDataConnection : DataConnection, IExpressionPreprocessor, IEntityServiceInterceptor
2729
{
2830
readonly IModel? _model;
2931
readonly Func<Expression, IDataContext, DbContext?, IModel?, Expression>? _transformFunc;
@@ -67,7 +69,7 @@ public LinqToDBForEFToolsDataConnection(
6769
_transformFunc = transformFunc;
6870
CopyDatabaseProperties();
6971
if (LinqToDBForEFTools.EnableChangeTracker)
70-
OnEntityCreated += OnEntityCreatedHandler;
72+
AddInterceptor(this);
7173
}
7274

7375
/// <summary>
@@ -80,9 +82,9 @@ public LinqToDBForEFToolsDataConnection(
8082
/// <param name="transformFunc">Expression converter.</param>
8183
public LinqToDBForEFToolsDataConnection(
8284
DbContext? context,
83-
[NotNull] IDataProvider dataProvider,
84-
[NotNull] IDbTransaction transaction,
85-
IModel? model,
85+
[NotNull] IDataProvider dataProvider,
86+
[NotNull] DbTransaction transaction,
87+
IModel? model,
8688
Func<Expression, IDataContext, DbContext?, IModel?, Expression>? transformFunc
8789
) : base(dataProvider, transaction)
8890
{
@@ -91,7 +93,7 @@ public LinqToDBForEFToolsDataConnection(
9193
_transformFunc = transformFunc;
9294
CopyDatabaseProperties();
9395
if (LinqToDBForEFTools.EnableChangeTracker)
94-
OnEntityCreated += OnEntityCreatedHandler;
96+
AddInterceptor(this);
9597
}
9698

9799
/// <summary>
@@ -105,7 +107,7 @@ public LinqToDBForEFToolsDataConnection(
105107
public LinqToDBForEFToolsDataConnection(
106108
DbContext? context,
107109
[NotNull] IDataProvider dataProvider,
108-
[NotNull] IDbConnection connection,
110+
[NotNull] DbConnection connection,
109111
IModel? model,
110112
Func<Expression, IDataContext, DbContext?, IModel?, Expression>? transformFunc) : base(dataProvider, connection)
111113
{
@@ -114,7 +116,7 @@ public LinqToDBForEFToolsDataConnection(
114116
_transformFunc = transformFunc;
115117
CopyDatabaseProperties();
116118
if (LinqToDBForEFTools.EnableChangeTracker)
117-
OnEntityCreated += OnEntityCreatedHandler;
119+
AddInterceptor(this);
118120
}
119121

120122
/// <summary>
@@ -157,7 +159,7 @@ public override bool Equals(object? obj)
157159
return true;
158160
}
159161

160-
if (obj.GetType() != this.GetType())
162+
if (obj.GetType() != GetType())
161163
{
162164
return false;
163165
}
@@ -174,35 +176,34 @@ public override int GetHashCode()
174176
}
175177
}
176178

177-
private void OnEntityCreatedHandler(EntityCreatedEventArgs args)
179+
object IEntityServiceInterceptor.EntityCreated(EntityCreatedEventData eventData, object entity)
178180
{
179181
// Do not allow to store in ChangeTracker temporary tables
180-
if ((args.TableOptions & TableOptions.IsTemporaryOptionSet) != 0)
181-
return;
182+
if ((eventData.TableOptions & TableOptions.IsTemporaryOptionSet) != 0)
183+
return entity;
182184

183185
// Do not allow to store in ChangeTracker tables from different server
184-
if (args.ServerName != null)
185-
return;
186+
if (eventData.ServerName != null)
187+
return entity;
186188

187189
if (!LinqToDBForEFTools.EnableChangeTracker
188190
|| !Tracking
189191
|| Context!.ChangeTracker.QueryTrackingBehavior == QueryTrackingBehavior.NoTracking)
190-
return;
192+
return entity;
191193

192-
var type = args.Entity.GetType();
194+
var type = entity.GetType();
193195
if (_lastType != type)
194196
{
195197
_lastType = type;
196198
_lastEntityType = Context.Model.FindEntityType(type);
197199
}
198200

199201
if (_lastEntityType == null)
200-
return;
201-
202+
return entity;
202203

203204
// Do not allow to store in ChangeTracker tables that has different name
204-
if (args.TableName != _lastEntityType.Relational().TableName)
205-
return;
205+
if (eventData.TableName != _lastEntityType.Relational().TableName)
206+
return entity;
206207

207208
if (_stateManager == null)
208209
_stateManager = Context.GetService<IStateManager>();
@@ -221,16 +222,16 @@ private void OnEntityCreatedHandler(EntityCreatedEventArgs args)
221222
});
222223

223224
if (retrievalFunc == null)
224-
return;
225+
return entity;
225226

226-
entry = retrievalFunc(_stateManager, args.Entity);
227+
entry = retrievalFunc(_stateManager, entity);
227228

228229
if (entry == null)
229230
{
230-
entry = _stateManager.StartTrackingFromQuery(_lastEntityType, args.Entity, ValueBuffer.Empty, null);
231+
entry = _stateManager.StartTrackingFromQuery(_lastEntityType, entity, ValueBuffer.Empty, null);
231232
}
232233

233-
args.Entity = entry.Entity;
234+
return entry.Entity;
234235
}
235236

236237
private Func<IStateManager, object, InternalEntityEntry?>? CreateEntityRetrievalFunc(IEntityType entityType)

0 commit comments

Comments
 (0)