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

Commit 3a273bc

Browse files
committed
Working on EF Core 3.0 upgrade.
1 parent 5fde6fb commit 3a273bc

28 files changed

+754
-197
lines changed

Source/LinqToDB.EntityFrameworkCore/EFCoreMetadataReader.cs

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@
1010
using Microsoft.EntityFrameworkCore;
1111
using Microsoft.EntityFrameworkCore.Internal;
1212
using Microsoft.EntityFrameworkCore.Metadata;
13-
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal;
1413
using Microsoft.EntityFrameworkCore.Metadata.Internal;
15-
using Microsoft.EntityFrameworkCore.Query.Expressions;
16-
using Microsoft.EntityFrameworkCore.Query.ExpressionVisitors;
14+
using Microsoft.EntityFrameworkCore.Query;
15+
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
1716

1817
namespace LinqToDB.EntityFrameworkCore
1918
{
@@ -27,10 +26,10 @@ namespace LinqToDB.EntityFrameworkCore
2726
internal class EFCoreMetadataReader : IMetadataReader
2827
{
2928
readonly IModel _model;
30-
private readonly SqlTranslatingExpressionVisitorDependencies _dependencies;
29+
private readonly RelationalSqlTranslatingExpressionVisitorDependencies _dependencies;
3130
private readonly ConcurrentDictionary<MemberInfo, EFCoreExpressionAttribute> _calculatedExtensions = new ConcurrentDictionary<MemberInfo, EFCoreExpressionAttribute>();
3231

33-
public EFCoreMetadataReader(IModel model, SqlTranslatingExpressionVisitorDependencies dependencies)
32+
public EFCoreMetadataReader(IModel model, RelationalSqlTranslatingExpressionVisitorDependencies dependencies)
3433
{
3534
_model = model;
3635
_dependencies = dependencies;
@@ -43,8 +42,7 @@ public T[] GetAttributes<T>(Type type, bool inherit = true) where T : Attribute
4342
{
4443
if (typeof(T) == typeof(TableAttribute))
4544
{
46-
var relational = et.Relational();
47-
return new[] { (T)(Attribute)new TableAttribute(relational.TableName) { Schema = relational.Schema } };
45+
return new[] { (T)(Attribute)new TableAttribute(et.GetTableName()) { Schema = et.GetSchema() } };
4846
}
4947
}
5048

@@ -76,19 +74,17 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru
7674
var primaryKeyOrder = 0;
7775
if (isPrimaryKey)
7876
{
79-
var pk = prop.GetContainingPrimaryKey();
77+
var pk = prop.FindContainingPrimaryKey();
8078
primaryKeyOrder = pk.Properties.Select((p, i) => new { p, index = i })
8179
.FirstOrDefault(v => v.p.GetIdentifyingMemberInfo() == memberInfo)?.index ?? 0;
8280
}
8381

84-
var relational = prop.Relational();
85-
8682
return new T[]{(T)(Attribute) new ColumnAttribute
8783
{
88-
Name = relational.ColumnName,
84+
Name = prop.GetColumnName(),
8985
Length = prop.GetMaxLength() ?? 0,
9086
CanBeNull = prop.IsNullable,
91-
DbType = relational.ColumnType,
87+
DbType = prop.GetColumnType(),
9288
IsPrimaryKey = isPrimaryKey,
9389
PrimaryKeyOrder = primaryKeyOrder,
9490
IsIdentity = prop.ValueGenerated == ValueGenerated.OnAdd,
@@ -170,21 +166,21 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru
170166
{
171167
var method = (MethodInfo) memberInfo;
172168

173-
var func = _model?.Relational().DbFunctions.FirstOrDefault(f => f.MethodInfo == method);
169+
var func = _model?.GetDbFunctions().FirstOrDefault(f => f.MethodInfo == method);
174170
if (func != null)
175171
return new T[]
176172
{
177173
(T) (Attribute) new Sql.FunctionAttribute
178174
{
179-
Name = func.FunctionName,
175+
Name = func.Name,
180176
ServerSideOnly = true
181177
}
182178
};
183179

184180
var functionAttributes = memberInfo.GetCustomAttributes<DbFunctionAttribute>(inherit);
185181
return functionAttributes.Select(f => (T) (Attribute) new Sql.FunctionAttribute
186182
{
187-
Name = f.FunctionName,
183+
Name = f.Name,
188184
ServerSideOnly = true,
189185
}).ToArray();
190186
}
@@ -214,14 +210,14 @@ private Sql.ExpressionAttribute GetDbFunctionFromMethodCall(Type type, MethodInf
214210

215211
var mcExpr = Expression.Call(methodInfo.IsStatic ? null : objExpr, methodInfo, parametersArray);
216212

217-
var newExpression = _dependencies.MethodCallTranslator.Translate(mcExpr, _model);
218-
if (newExpression != null && newExpression != mcExpr)
219-
{
220-
if (!methodInfo.IsStatic)
221-
parametersArray = new Expression[] { objExpr }.Concat(parametersArray).ToArray();
222-
223-
result = ConvertToExpressionAttribute(methodInfo, newExpression, parametersArray);
224-
}
213+
// var newExpression = _dependencies.MethodCallTranslatorProvider.Translate(_model, null, mcExpr, new List<SqlExpression>());
214+
// if (newExpression != null && newExpression != mcExpr)
215+
// {
216+
// if (!methodInfo.IsStatic)
217+
// parametersArray = new Expression[] { objExpr }.Concat(parametersArray).ToArray();
218+
//
219+
// result = ConvertToExpressionAttribute(methodInfo, newExpression, parametersArray);
220+
// }
225221
}
226222

227223
return result;
@@ -246,12 +242,12 @@ private Sql.ExpressionAttribute GetDbFunctionFromProperty(Type type, PropertyInf
246242
var objExpr = Expression.Constant(DefaultValue.GetValue(type), type);
247243
var mcExpr = Expression.MakeMemberAccess(objExpr, propInfo);
248244

249-
var newExpression = _dependencies.MemberTranslator.Translate(mcExpr);
250-
if (newExpression != null && newExpression != mcExpr)
251-
{
252-
var parametersArray = new Expression[] { objExpr };
253-
result = ConvertToExpressionAttribute(propInfo, newExpression, parametersArray);
254-
}
245+
// var newExpression = _dependencies.MemberTranslator.Translate(mcExpr);
246+
// if (newExpression != null && newExpression != mcExpr)
247+
// {
248+
// var parametersArray = new Expression[] { objExpr };
249+
// result = ConvertToExpressionAttribute(propInfo, newExpression, parametersArray);
250+
// }
255251
}
256252

257253
return result;
@@ -273,9 +269,9 @@ string PrepareExpressionText(Expression expr)
273269

274270
if (expr is SqlFunctionExpression sqlFunction)
275271
{
276-
var text = sqlFunction.FunctionName;
272+
var text = sqlFunction.Name;
277273
if (!sqlFunction.Schema.IsNullOrEmpty())
278-
text = sqlFunction.Schema + "." + sqlFunction.FunctionName;
274+
text = sqlFunction.Schema + "." + sqlFunction.Name;
279275

280276
if (!sqlFunction.IsNiladic)
281277
{
@@ -328,7 +324,7 @@ private static Expression UnwrapConverted(Expression expr)
328324
{
329325
if (expr is SqlFunctionExpression func)
330326
{
331-
if (string.Equals(func.FunctionName, "COALESCE", StringComparison.InvariantCultureIgnoreCase) &&
327+
if (string.Equals(func.Name, "COALESCE", StringComparison.InvariantCultureIgnoreCase) &&
332328
func.Arguments.Count == 2 && func.Arguments[1].NodeType == ExpressionType.Default)
333329
return UnwrapConverted(func.Arguments[0]);
334330
}

Source/LinqToDB.EntityFrameworkCore/ILinqToDBForEFTools.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
using Microsoft.EntityFrameworkCore;
55
using Microsoft.EntityFrameworkCore.Infrastructure;
66
using Microsoft.EntityFrameworkCore.Metadata;
7-
using Microsoft.EntityFrameworkCore.Query.ExpressionVisitors;
7+
using Microsoft.EntityFrameworkCore.Query;
88
using Microsoft.Extensions.Logging;
99

1010
namespace LinqToDB.EntityFrameworkCore
@@ -38,7 +38,7 @@ public interface ILinqToDBForEFTools
3838
/// <param name="model">EF.Core data model.</param>
3939
/// <param name="dependencies"></param>
4040
/// <returns>LINQ To DB metadata provider for specified EF.Core model. Can return <c>null</c>.</returns>
41-
IMetadataReader CreateMetadataReader(IModel model, SqlTranslatingExpressionVisitorDependencies dependencies);
41+
IMetadataReader CreateMetadataReader(IModel model, RelationalSqlTranslatingExpressionVisitorDependencies dependencies);
4242

4343
/// <summary>
4444
/// Creates mapping schema using provided EF.Core data model and metadata provider.

Source/LinqToDB.EntityFrameworkCore/Internal/LinqToDBForEFQueryProvider.cs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
using System.Collections.Generic;
44
using System.Linq;
55
using System.Linq.Expressions;
6+
using System.Reflection;
67
using System.Threading;
78
using System.Threading.Tasks;
89

910
using Microsoft.EntityFrameworkCore.Query.Internal;
1011

1112
using JetBrains.Annotations;
13+
using LinqToDB.Expressions;
1214

1315
namespace LinqToDB.EntityFrameworkCore.Internal
1416
{
@@ -54,6 +56,16 @@ public TResult Execute<TResult>(Expression expression)
5456
return QueryProvider.Execute<TResult>(expression);
5557
}
5658

59+
private static MethodInfo _executeAsyncMethodInfo =
60+
MemberHelper.MethodOf((IQueryProviderAsync p) => p.ExecuteAsync<int>(null, default)).GetGenericMethodDefinition();
61+
62+
TResult IAsyncQueryProvider.ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken)
63+
{
64+
var item = typeof(TResult).GetGenericArguments()[0];
65+
var method = _executeAsyncMethodInfo.MakeGenericMethod(item);
66+
return (TResult) method.Invoke(QueryProvider, new object[] { expression, cancellationToken });
67+
}
68+
5769
public System.Collections.Generic.IAsyncEnumerable<TResult> ExecuteAsync<TResult>(Expression expression)
5870
{
5971
return new AsyncEnumerableAdaper<TResult>(QueryProvider.ExecuteAsync<TResult>(expression));
@@ -87,9 +99,9 @@ IEnumerator IEnumerable.GetEnumerator()
8799

88100
#endregion
89101

90-
System.Collections.Generic.IAsyncEnumerator<T> System.Collections.Generic.IAsyncEnumerable<T>.GetEnumerator()
102+
System.Collections.Generic.IAsyncEnumerator<T> System.Collections.Generic.IAsyncEnumerable<T>.GetAsyncEnumerator(CancellationToken cancellationTokent)
91103
{
92-
return ExecuteAsync<T>(Expression).GetEnumerator();
104+
return ExecuteAsync<T>(Expression).GetAsyncEnumerator(CancellationToken.None);
93105
}
94106

95107
class AsyncEnumerableAdaper<TEntity> : System.Collections.Generic.IAsyncEnumerable<TEntity>
@@ -101,7 +113,7 @@ public AsyncEnumerableAdaper(IAsyncEnumerable<TEntity> asyncEnumerable)
101113
AsyncEnumerable = asyncEnumerable;
102114
}
103115

104-
public System.Collections.Generic.IAsyncEnumerator<TEntity> GetEnumerator()
116+
public System.Collections.Generic.IAsyncEnumerator<TEntity> GetAsyncEnumerator(CancellationToken cancellationToken = new CancellationToken())
105117
{
106118
return new AsyncEnumeratorAdapter<TEntity>(AsyncEnumerable.GetEnumerator());
107119
}
@@ -116,17 +128,18 @@ public AsyncEnumeratorAdapter(IAsyncEnumerator<TEntity> asyncEnumerator)
116128
AsyncEnumerator = asyncEnumerator;
117129
}
118130

119-
public void Dispose()
131+
public ValueTask<bool> MoveNextAsync()
120132
{
121-
AsyncEnumerator?.Dispose();
133+
return new ValueTask<bool>(AsyncEnumerator.MoveNext(CancellationToken.None));
122134
}
123135

124-
public Task<bool> MoveNext(CancellationToken cancellationToken)
136+
public TEntity Current => AsyncEnumerator.Current;
137+
138+
public ValueTask DisposeAsync()
125139
{
126-
return AsyncEnumerator.MoveNext(cancellationToken);
140+
AsyncEnumerator?.Dispose();
141+
return default;
127142
}
128-
129-
public TEntity Current => AsyncEnumerator.Current;
130143
}
131144

132145
}

Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFTools.Mapping.cs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -93,25 +93,25 @@ static void InitializeSqlServerMapping()
9393
Linq.Expressions.MapMember(method, lambda);
9494
}
9595

96-
var freeTextMethod = sqlServerMethods.FirstOrDefault(m => m.Name == "FreeText" && m.GetParameters().Length == 3);
97-
if (freeTextMethod != null)
98-
{
99-
var propertyReferenceParam = Expression.Parameter(typeof(string), "propertyReference");
100-
var freeTextParam = Expression.Parameter(typeof(string), "freeText");
101-
102-
var lambda = Expression.Lambda(
103-
Expression.Call(
104-
MemberHelper.MethodOf(() => Sql.FreeText(null, null)),
105-
propertyReferenceParam,
106-
freeTextParam
107-
),
108-
dbFunctionsParameter,
109-
propertyReferenceParam,
110-
freeTextParam
111-
);
112-
113-
Linq.Expressions.MapMember(freeTextMethod, lambda);
114-
}
96+
// var freeTextMethod = sqlServerMethods.FirstOrDefault(m => m.Name == "FreeText" && m.GetParameters().Length == 3);
97+
// if (freeTextMethod != null)
98+
// {
99+
// var propertyReferenceParam = Expression.Parameter(typeof(string), "propertyReference");
100+
// var freeTextParam = Expression.Parameter(typeof(string), "freeText");
101+
//
102+
// var lambda = Expression.Lambda(
103+
// Expression.Call(
104+
// MemberHelper.MethodOf(() => Sql.FreeText(null, null)),
105+
// propertyReferenceParam,
106+
// freeTextParam
107+
// ),
108+
// dbFunctionsParameter,
109+
// propertyReferenceParam,
110+
// freeTextParam
111+
// );
112+
//
113+
// Linq.Expressions.MapMember(freeTextMethod, lambda);
114+
// }
115115

116116
}
117117

Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFTools.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
using Microsoft.Extensions.Logging;
1212

1313
using JetBrains.Annotations;
14-
using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators;
15-
using Microsoft.EntityFrameworkCore.Query.ExpressionVisitors;
14+
using Microsoft.EntityFrameworkCore.Query;
1615

1716
namespace LinqToDB.EntityFrameworkCore
1817
{
@@ -122,7 +121,7 @@ static LinqToDBForEFTools()
122121
/// <param name="dependencies"></param>
123122
/// <returns>LINQ To DB metadata provider.</returns>
124123
public static IMetadataReader GetMetadataReader([JetBrains.Annotations.CanBeNull] IModel model,
125-
SqlTranslatingExpressionVisitorDependencies dependencies)
124+
RelationalSqlTranslatingExpressionVisitorDependencies dependencies)
126125
{
127126
if (model == null)
128127
return _defaultMeadataReader.Value;
@@ -214,7 +213,7 @@ public static IDataProvider GetDataProvider(EFProviderInfo info, EFConnectionInf
214213
/// <param name="dependencies"></param>
215214
/// <returns>Mapping schema for provided EF.Core model.</returns>
216215
public static MappingSchema GetMappingSchema(IModel model,
217-
SqlTranslatingExpressionVisitorDependencies dependencies)
216+
RelationalSqlTranslatingExpressionVisitorDependencies dependencies)
218217
{
219218
return Implementation.GetMappingSchema(model, GetMetadataReader(model, dependencies));
220219
}
@@ -275,7 +274,7 @@ public static DataConnection CreateLinqToDbConnection(this DbContext context,
275274
if (logger != null)
276275
dc.OnTraceConnection = t => Implementation.LogConnectionTrace(t, logger);
277276

278-
var dependencies = context.GetService<SqlTranslatingExpressionVisitorDependencies>();
277+
var dependencies = context.GetService<RelationalSqlTranslatingExpressionVisitorDependencies>();
279278
var mappingSchema = GetMappingSchema(context.Model, dependencies);
280279
if (mappingSchema != null)
281280
dc.AddMappingSchema(mappingSchema);
@@ -301,7 +300,7 @@ public static IDataContext CreateLinqToDbContext(this DbContext context,
301300

302301
var connectionInfo = GetConnectionInfo(info);
303302
var provider = GetDataProvider(info, connectionInfo);
304-
var dependencies = context.GetService<SqlTranslatingExpressionVisitorDependencies>();
303+
var dependencies = context.GetService<RelationalSqlTranslatingExpressionVisitorDependencies>();
305304
var mappingSchema = GetMappingSchema(context.Model, dependencies);
306305
var logger = CreateLogger(info.Options);
307306

@@ -360,7 +359,7 @@ public static DataConnection CreateLinq2DbConnectionDetached([JetBrains.Annotati
360359
if (logger != null)
361360
dc.OnTraceConnection = t => Implementation.LogConnectionTrace(t, logger);
362361

363-
var dependencies = context.GetService<SqlTranslatingExpressionVisitorDependencies>();
362+
var dependencies = context.GetService<RelationalSqlTranslatingExpressionVisitorDependencies>();
364363
var mappingSchema = GetMappingSchema(context.Model, dependencies);
365364
if (mappingSchema != null)
366365
dc.AddMappingSchema(mappingSchema);

0 commit comments

Comments
 (0)