-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ef.core 7 support #263
ef.core 7 support #263
Changes from all commits
67def6a
8d90511
b85d748
88a81a7
6943375
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,8 @@ | ||
#ignore thumbnails created by windows | ||
Thumbs.db | ||
#Ignore files build by Visual Studio | ||
*.obj | ||
*.pdb | ||
#Ignore files build by IDE | ||
*.user | ||
*.aps | ||
*.pch | ||
*.vspscc | ||
*_i.c | ||
*_p.c | ||
*.ncb | ||
*.suo | ||
*.tlb | ||
*.tlh | ||
*.bak | ||
*.cache | ||
*.ilk | ||
*.log | ||
*.cs.ide | ||
[Bb]in | ||
[Dd]ebug*/ | ||
*.lib | ||
*.sbr | ||
bin/ | ||
obj/ | ||
[Rr]elease*/ | ||
_ReSharper*/ | ||
[Tt]est[Rr]esult* | ||
linq2db.sln.docstates | ||
Tests/**/UserDataProviders*.* | ||
NuGet/*.nupkg | ||
!*.dll | ||
!*.exe | ||
!*.pdb | ||
linq2db.sln.ide/graph | ||
linq2db.sln.ide/ | ||
!Redist/** | ||
/packages | ||
/.vs/* | ||
*.lock.json | ||
/api | ||
/linq2db.github.io | ||
#cake | ||
/tools | ||
/.tools | ||
/.tools/ | ||
/.idea/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,27 @@ | ||
<Project> | ||
<ItemGroup> | ||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.2.0" /> | ||
<PackageVersion Include="NUnit3TestAdapter" Version="4.2.1" /> | ||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.4.0" /> | ||
<PackageVersion Include="NUnit3TestAdapter" Version="4.3.0" /> | ||
<PackageVersion Include="NUnit" Version="3.13.3" /> | ||
<PackageVersion Include="FluentAssertions" Version="6.6.0" /> | ||
<PackageVersion Include="FluentAssertions" Version="6.8.0" /> | ||
|
||
<PackageVersion Include="linq2db" Version="4.3.0" /> | ||
<PackageVersion Include="linq2db.Tools" Version="4.3.0" /> | ||
|
||
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="1.1.1" /> | ||
|
||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.17" /> | ||
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="5.0.17" /> | ||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.0" /> | ||
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.0" /> | ||
|
||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="5.0.0" /> | ||
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" /> | ||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="7.0.0" /> | ||
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" /> | ||
|
||
<PackageVersion Include="Pomelo.EntityFrameworkCore.MySql" Version="5.0.4" /> | ||
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.10" /> | ||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.17" /> | ||
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.17" /> | ||
<PackageVersion Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.2" /> | ||
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.0" /> | ||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.0" /> | ||
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.0" /> | ||
|
||
<PackageVersion Include="EntityFrameworkCore.FSharp" Version="5.0.3" /> | ||
<PackageVersion Include="FSharp.Core" Version="6.0.5" /> | ||
<PackageVersion Include="EntityFrameworkCore.FSharp" Version="6.0.7" /> | ||
<PackageVersion Include="FSharp.Core" Version="7.0.0" /> | ||
</ItemGroup> | ||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,4 @@ | ||
using System; | ||
using System.Collections; | ||
using System.Collections.Concurrent; | ||
using System.Collections.Generic; | ||
using System.Data; | ||
|
@@ -31,7 +30,7 @@ namespace LinqToDB.EntityFrameworkCore | |
/// <summary> | ||
/// LINQ To DB metadata reader for EF.Core model. | ||
/// </summary> | ||
internal class EFCoreMetadataReader : IMetadataReader | ||
internal sealed class EFCoreMetadataReader : IMetadataReader | ||
{ | ||
readonly IModel? _model; | ||
private readonly RelationalSqlTranslatingExpressionVisitorDependencies? _dependencies; | ||
|
@@ -40,8 +39,7 @@ internal class EFCoreMetadataReader : IMetadataReader | |
private readonly ConcurrentDictionary<MemberInfo, EFCoreExpressionAttribute?> _calculatedExtensions = new(); | ||
private readonly IDiagnosticsLogger<DbLoggerCategory.Query>? _logger; | ||
|
||
public EFCoreMetadataReader( | ||
IModel? model, IInfrastructure<IServiceProvider>? accessor) | ||
public EFCoreMetadataReader(IModel? model, IInfrastructure<IServiceProvider>? accessor) | ||
{ | ||
_model = model; | ||
if (accessor != null) | ||
|
@@ -61,7 +59,7 @@ public T[] GetAttributes<T>(Type type, bool inherit = true) where T : Attribute | |
if (typeof(T) == typeof(TableAttribute)) | ||
{ | ||
var storeObjectId = GetStoreObjectIdentifier(et); | ||
return new[] { (T)(Attribute)new TableAttribute(storeObjectId!.Value.Name) { Schema = storeObjectId!.Value.Schema } }; | ||
return new[] { (T)(Attribute)new TableAttribute() { Schema = storeObjectId?.Schema, Name = storeObjectId?.Name } }; | ||
} | ||
if (typeof(T) == typeof(QueryFilterAttribute)) | ||
{ | ||
|
@@ -208,7 +206,7 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru | |
|
||
if (prop != null) | ||
{ | ||
var discriminator = et.GetDiscriminatorProperty(); | ||
var discriminator = et.FindDiscriminatorProperty(); | ||
|
||
var isPrimaryKey = prop.IsPrimaryKey(); | ||
var primaryKeyOrder = 0; | ||
|
@@ -225,14 +223,14 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru | |
if (_annotationProvider != null && storeObjectId != null) | ||
{ | ||
if (prop.FindColumn(storeObjectId.Value) is IColumn column) | ||
annotations = annotations.Concat(_annotationProvider.For(column)); | ||
annotations = annotations.Concat(_annotationProvider.For(column, false)); | ||
} | ||
|
||
var isIdentity = annotations | ||
.Any(a => | ||
{ | ||
if (a.Name.EndsWith(":ValueGenerationStrategy")) | ||
return a.Value?.ToString()!.Contains("Identity") == true; | ||
return a.Value?.ToString()?.Contains("Identity") == true; | ||
|
||
if (a.Name.EndsWith(":Autoincrement")) | ||
return a.Value is bool b && b; | ||
|
@@ -242,7 +240,7 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru | |
{ | ||
if (a.Value is string str) | ||
{ | ||
return str.ToLower().Contains("nextval"); | ||
return str.ToLowerInvariant().Contains("nextval"); | ||
} | ||
} | ||
|
||
|
@@ -259,7 +257,8 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru | |
} | ||
else | ||
{ | ||
dataType = SqlDataType.GetDataType(typeMapping.ClrType).Type.DataType; | ||
var ms = _model != null ? LinqToDBForEFTools.GetMappingSchema(_model, null) : MappingSchema.Default; | ||
dataType = ms.GetDataType(typeMapping.ClrType).Type.DataType; | ||
} | ||
} | ||
|
||
|
@@ -278,7 +277,7 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru | |
{ | ||
(T)(Attribute)new ColumnAttribute | ||
{ | ||
Name = prop.GetColumnName(storeObjectId!.Value), | ||
Name = storeObjectId != null ? prop.GetColumnName(storeObjectId.Value) : null, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. storeObjectId is not value type anymore? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is, but there were assumption that GetStoreObjectIdentifier will return non-null value. I'm not sure it is always true, so I've replaced code a bit to treat it as nullable value to avoid NRE |
||
Length = prop.GetMaxLength() ?? 0, | ||
CanBeNull = prop.IsNullable, | ||
DbType = prop.GetColumnType(), | ||
|
@@ -408,7 +407,7 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru | |
return Array.Empty<T>(); | ||
} | ||
|
||
class ValueConverter : IValueConverter | ||
sealed class ValueConverter : IValueConverter | ||
{ | ||
public ValueConverter( | ||
LambdaExpression convertToProviderExpression, | ||
|
@@ -425,7 +424,7 @@ public ValueConverter( | |
|
||
} | ||
|
||
class SqlTransparentExpression : SqlExpression | ||
sealed class SqlTransparentExpression : SqlExpression | ||
{ | ||
public Expression Expression { get; } | ||
|
||
|
@@ -439,7 +438,7 @@ protected override void Print(ExpressionPrinter expressionPrinter) | |
expressionPrinter.Print(Expression); | ||
} | ||
|
||
protected bool Equals(SqlTransparentExpression other) | ||
private bool Equals(SqlTransparentExpression other) | ||
{ | ||
return ReferenceEquals(this, other); | ||
} | ||
|
@@ -596,23 +595,24 @@ string PrepareExpressionText(Expression? expr) | |
return text; | ||
} | ||
|
||
// https://github.com/npgsql/efcore.pg/blob/main/src/EFCore.PG/Query/Expressions/Internal/PostgresBinaryExpression.cs | ||
if (newExpression.GetType().Name == "PostgresBinaryExpression") | ||
{ | ||
// Handling NpgSql's PostgresBinaryExpression | ||
|
||
var left = newExpression.GetType().GetProperty("Left")?.GetValue(newExpression) as Expression; | ||
var right = newExpression.GetType().GetProperty("Right")?.GetValue(newExpression) as Expression; | ||
var left = (Expression)newExpression.GetType().GetProperty("Left")!.GetValue(newExpression)!; | ||
var right = (Expression)newExpression.GetType().GetProperty("Right")!.GetValue(newExpression)!; | ||
|
||
var operand = newExpression.GetType().GetProperty("OperatorType")?.GetValue(newExpression)!.ToString(); | ||
var operand = newExpression.GetType().GetProperty("OperatorType")!.GetValue(newExpression)!.ToString()!; | ||
|
||
var operandExpr = operand switch | ||
{ | ||
"Contains" | ||
when left!.Type.Name == "NpgsqlInetTypeMapping" || | ||
when left.Type.Name == "NpgsqlInetTypeMapping" || | ||
left.Type.Name == "NpgsqlCidrTypeMapping" | ||
=> ">>", | ||
"ContainedBy" | ||
when left!.Type.Name == "NpgsqlInetTypeMapping" || | ||
when left.Type.Name == "NpgsqlInetTypeMapping" || | ||
left.Type.Name == "NpgsqlCidrTypeMapping" | ||
=> "<<", | ||
"Contains" => "@>", | ||
|
@@ -674,7 +674,7 @@ private static Expression UnwrapConverted(Expression expr) | |
if (expr is SqlFunctionExpression func) | ||
{ | ||
if (string.Equals(func.Name, "COALESCE", StringComparison.InvariantCultureIgnoreCase) && | ||
func.Arguments!.Count == 2 && func.Arguments[1].NodeType == ExpressionType.Extension) | ||
func.Arguments?.Count == 2 && func.Arguments[1].NodeType == ExpressionType.Extension) | ||
return UnwrapConverted(func.Arguments[0]); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
net7.0. ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dotnet/efcore#26994 (comment)