ef.core 7 support (#263)
* efcore 7 support * fix connection strings * suppress dependency errors * disable C# 11 features temporary * there will be no API-breaking changes in this area within major version
This commit is contained in:
Родитель
2ff736967c
Коммит
d1fd30f1d9
|
@ -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/
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>5.13.0</Version>
|
||||
<Version>7.0.0</Version>
|
||||
|
||||
<Authors>Svyatoslav Danyliv, Igor Tkachev, Dmitry Lukashenko, Ilya Chudin</Authors>
|
||||
<Product>Linq to DB</Product>
|
||||
|
@ -27,8 +27,11 @@
|
|||
<GenerateAssemblyVersionAttribute>true</GenerateAssemblyVersionAttribute>
|
||||
<GenerateAssemblyFileVersionAttribute>true</GenerateAssemblyFileVersionAttribute>
|
||||
<GenerateNeutralResourcesLanguageAttribute>false</GenerateNeutralResourcesLanguageAttribute>
|
||||
<DisableImplicitNamespaceImports>true</DisableImplicitNamespaceImports>
|
||||
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
|
||||
<TargetFrameworks>net6.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
<Import Project="linq2db.Default.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFrameworks>net7.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="NUnit3TestAdapter">
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<title>Linq to DB (linq2db) extensions for Entity Framework Core</title>
|
||||
<authors>Igor Tkachev, Ilya Chudin, Svyatoslav Danyliv, Dmitry Lukashenko</authors>
|
||||
<owners>Igor Tkachev, Ilya Chudin, Svyatoslav Danyliv, Dmitry Lukashenko</owners>
|
||||
<copyright>Copyright © 2020-2021 Igor Tkachev, Ilya Chudin, Svyatoslav Danyliv, Dmitry Lukashenko</copyright>
|
||||
<copyright>Copyright © 2020-2022 Igor Tkachev, Ilya Chudin, Svyatoslav Danyliv, Dmitry Lukashenko</copyright>
|
||||
<description>Allows to execute Linq to DB (linq2db) queries in Entity Framework Core DbContext.</description>
|
||||
<summary />
|
||||
<tags>linq linq2db LinqToDB ORM database entity-framework-core EntityFrameworkCore EFCore DB SQL SqlServer SqlCe SqlServerCe MySql Firebird SQLite Oracle ODP PostgreSQL DB2</tags>
|
||||
|
@ -14,8 +14,8 @@
|
|||
<projectUrl>https://github.com/linq2db/linq2db.EntityFrameworkCore</projectUrl>
|
||||
<license type="file">MIT-LICENSE.txt</license>
|
||||
<dependencies>
|
||||
<group targetFramework=".NETStandard2.1">
|
||||
<dependency id="Microsoft.EntityFrameworkCore.Relational" version="5.0.17" />
|
||||
<group targetFramework="net6.0">
|
||||
<dependency id="Microsoft.EntityFrameworkCore.Relational" version="7.0.0" />
|
||||
<dependency id="linq2db" version="4.3.0" />
|
||||
</group>
|
||||
</dependencies>
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
/// <summary>
|
||||
/// Contains database connectivity information, extracted from EF.Core.
|
||||
/// </summary>
|
||||
public class EFConnectionInfo
|
||||
public sealed class EFConnectionInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets database connection instance.
|
||||
|
|
|
@ -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 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
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 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
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 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
|
||||
if (prop != null)
|
||||
{
|
||||
var discriminator = et.GetDiscriminatorProperty();
|
||||
var discriminator = et.FindDiscriminatorProperty();
|
||||
|
||||
var isPrimaryKey = prop.IsPrimaryKey();
|
||||
var primaryKeyOrder = 0;
|
||||
|
@ -225,14 +223,14 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
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 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
{
|
||||
if (a.Value is string str)
|
||||
{
|
||||
return str.ToLower().Contains("nextval");
|
||||
return str.ToLowerInvariant().Contains("nextval");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -259,7 +257,8 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
}
|
||||
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 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
{
|
||||
(T)(Attribute)new ColumnAttribute
|
||||
{
|
||||
Name = prop.GetColumnName(storeObjectId!.Value),
|
||||
Name = storeObjectId != null ? prop.GetColumnName(storeObjectId.Value) : null,
|
||||
Length = prop.GetMaxLength() ?? 0,
|
||||
CanBeNull = prop.IsNullable,
|
||||
DbType = prop.GetColumnType(),
|
||||
|
@ -408,7 +407,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
return Array.Empty<T>();
|
||||
}
|
||||
|
||||
class ValueConverter : IValueConverter
|
||||
sealed class ValueConverter : IValueConverter
|
||||
{
|
||||
public ValueConverter(
|
||||
LambdaExpression convertToProviderExpression,
|
||||
|
@ -425,7 +424,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
|
||||
}
|
||||
|
||||
class SqlTransparentExpression : SqlExpression
|
||||
sealed class SqlTransparentExpression : SqlExpression
|
||||
{
|
||||
public Expression Expression { get; }
|
||||
|
||||
|
@ -439,7 +438,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
expressionPrinter.Print(Expression);
|
||||
}
|
||||
|
||||
protected bool Equals(SqlTransparentExpression other)
|
||||
private bool Equals(SqlTransparentExpression other)
|
||||
{
|
||||
return ReferenceEquals(this, other);
|
||||
}
|
||||
|
@ -596,23 +595,24 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
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 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
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]);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
/// <summary>
|
||||
/// Required integration information about underlying database provider, extracted from EF.Core.
|
||||
/// </summary>
|
||||
public class EFProviderInfo
|
||||
public sealed class EFProviderInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets database connection instance.
|
||||
|
|
|
@ -119,6 +119,5 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
/// Entities will be attached only if AsNoTracking() is not used in query and DbContext is configured to track entities.
|
||||
/// </summary>
|
||||
bool EnableChangeTracker { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ namespace LinqToDB.EntityFrameworkCore.Internal
|
|||
{
|
||||
var item = typeof(TResult).GetGenericArguments()[0];
|
||||
var method = _executeAsyncMethodInfo.MakeGenericMethod(item);
|
||||
return (TResult) method.Invoke(QueryProvider, new object[] { expression, cancellationToken })!;
|
||||
return (TResult)method.Invoke(QueryProvider, new object[] { expression, cancellationToken })!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
/// <summary>
|
||||
/// LINQ To DB async extensions adapter to call EF.Core functionality instead of default implementation.
|
||||
/// </summary>
|
||||
public class LinqToDBExtensionsAdapter : IExtensionsAdapter
|
||||
public sealed class LinqToDBExtensionsAdapter : IExtensionsAdapter
|
||||
{
|
||||
/// <inheritdoc cref="EntityFrameworkQueryableExtensions.AsAsyncEnumerable{TSource}(IQueryable{TSource})"/>
|
||||
public IAsyncEnumerable<TSource> AsAsyncEnumerable<TSource>(IQueryable<TSource> source)
|
||||
|
@ -90,18 +90,14 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
public Task<TSource?> FirstOrDefaultAsync<TSource>(
|
||||
IQueryable<TSource> source,
|
||||
CancellationToken token)
|
||||
#pragma warning disable CS8619 // Nullability of reference types in value doesn't match target type.
|
||||
=> EntityFrameworkQueryableExtensions.FirstOrDefaultAsync(source, token);
|
||||
#pragma warning restore CS8619 // Nullability of reference types in value doesn't match target type.
|
||||
|
||||
/// <inheritdoc cref="EntityFrameworkQueryableExtensions.FirstOrDefaultAsync{TSource}(IQueryable{TSource}, Expression{Func{TSource, bool}}, CancellationToken)"/>
|
||||
public Task<TSource?> FirstOrDefaultAsync<TSource>(
|
||||
IQueryable<TSource> source,
|
||||
Expression<Func<TSource,bool>> predicate,
|
||||
CancellationToken token)
|
||||
#pragma warning disable CS8619 // Nullability of reference types in value doesn't match target type.
|
||||
=> EntityFrameworkQueryableExtensions.FirstOrDefaultAsync(source, predicate, token);
|
||||
#pragma warning restore CS8619 // Nullability of reference types in value doesn't match target type.
|
||||
|
||||
/// <inheritdoc cref="EntityFrameworkQueryableExtensions.SingleAsync{TSource}(IQueryable{TSource}, CancellationToken)"/>
|
||||
public Task<TSource> SingleAsync<TSource>(
|
||||
|
@ -120,18 +116,14 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
public Task<TSource?> SingleOrDefaultAsync<TSource>(
|
||||
IQueryable<TSource> source,
|
||||
CancellationToken token)
|
||||
#pragma warning disable CS8619 // Nullability of reference types in value doesn't match target type.
|
||||
=> EntityFrameworkQueryableExtensions.SingleOrDefaultAsync(source, token);
|
||||
#pragma warning restore CS8619 // Nullability of reference types in value doesn't match target type.
|
||||
|
||||
/// <inheritdoc cref="EntityFrameworkQueryableExtensions.SingleOrDefaultAsync{TSource}(IQueryable{TSource}, Expression{Func{TSource, bool}}, CancellationToken)"/>
|
||||
public Task<TSource?> SingleOrDefaultAsync<TSource>(
|
||||
IQueryable<TSource> source,
|
||||
Expression<Func<TSource,bool>> predicate,
|
||||
CancellationToken token)
|
||||
#pragma warning disable CS8619 // Nullability of reference types in value doesn't match target type.
|
||||
=> EntityFrameworkQueryableExtensions.SingleOrDefaultAsync(source, predicate, token);
|
||||
#pragma warning restore CS8619 // Nullability of reference types in value doesn't match target type.
|
||||
|
||||
/// <inheritdoc cref="EntityFrameworkQueryableExtensions.ContainsAsync{TSource}(IQueryable{TSource}, TSource, CancellationToken)"/>
|
||||
public Task<bool> ContainsAsync<TSource>(
|
||||
|
|
|
@ -75,13 +75,13 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
=> EntityFrameworkQueryableExtensions.FirstAsync(source, predicate, cancellationToken);
|
||||
|
||||
/// <inheritdoc cref="EntityFrameworkQueryableExtensions.FirstOrDefaultAsync{TSource}(IQueryable{TSource}, CancellationToken)"/>
|
||||
public static Task<TSource> FirstOrDefaultAsyncEF<TSource>(
|
||||
public static Task<TSource?> FirstOrDefaultAsyncEF<TSource>(
|
||||
this IQueryable<TSource> source,
|
||||
CancellationToken cancellationToken = default)
|
||||
=> EntityFrameworkQueryableExtensions.FirstOrDefaultAsync(source, cancellationToken);
|
||||
|
||||
/// <inheritdoc cref="EntityFrameworkQueryableExtensions.FirstOrDefaultAsync{TSource}(IQueryable{TSource}, Expression{Func{TSource, bool}}, CancellationToken)"/>
|
||||
public static Task<TSource> FirstOrDefaultAsyncEF<TSource>(
|
||||
public static Task<TSource?> FirstOrDefaultAsyncEF<TSource>(
|
||||
this IQueryable<TSource> source,
|
||||
Expression<Func<TSource,bool>> predicate,
|
||||
CancellationToken cancellationToken = default)
|
||||
|
@ -101,13 +101,13 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
=> EntityFrameworkQueryableExtensions.SingleAsync(source, predicate, cancellationToken);
|
||||
|
||||
/// <inheritdoc cref="EntityFrameworkQueryableExtensions.SingleOrDefaultAsync{TSource}(IQueryable{TSource}, CancellationToken)"/>
|
||||
public static Task<TSource> SingleOrDefaultAsyncEF<TSource>(
|
||||
public static Task<TSource?> SingleOrDefaultAsyncEF<TSource>(
|
||||
this IQueryable<TSource> source,
|
||||
CancellationToken cancellationToken = default)
|
||||
=> EntityFrameworkQueryableExtensions.SingleOrDefaultAsync(source, cancellationToken);
|
||||
|
||||
/// <inheritdoc cref="EntityFrameworkQueryableExtensions.SingleOrDefaultAsync{TSource}(IQueryable{TSource}, Expression{Func{TSource, bool}}, CancellationToken)"/>
|
||||
public static Task<TSource> SingleOrDefaultAsyncEF<TSource>(
|
||||
public static Task<TSource?> SingleOrDefaultAsyncEF<TSource>(
|
||||
this IQueryable<TSource> source,
|
||||
Expression<Func<TSource,bool>> predicate,
|
||||
CancellationToken cancellationToken = default)
|
||||
|
|
|
@ -12,7 +12,6 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
|
||||
public partial class LinqToDBForEFTools
|
||||
{
|
||||
|
||||
static void InitializeMapping()
|
||||
{
|
||||
Linq.Expressions.MapMember(
|
||||
|
@ -59,7 +58,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
var dateDiffStr = "DateDiff";
|
||||
var dateDiffMethods = sqlServerMethods.Where(m => m.Name.StartsWith(dateDiffStr)).ToArray();
|
||||
|
||||
var dateDiffMethod = MemberHelper.MethodOf(() => Sql.DateDiff(Sql.DateParts.Day, null, null));
|
||||
var dateDiffMethod = MemberHelper.MethodOf(() => Sql.DateDiff(Sql.DateParts.Day, (DateTime?)null, null));
|
||||
|
||||
foreach (var method in dateDiffMethods)
|
||||
{
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
using Expressions;
|
||||
|
||||
using Internal;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
/// <summary>
|
||||
/// EF Core <see cref="DbContext"/> extensions to call LINQ To DB functionality.
|
||||
|
@ -65,7 +66,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
var newExpression = queryable.Expression;
|
||||
|
||||
var result = (IQueryable)instantiator.MakeGenericMethod(queryable.ElementType)
|
||||
.Invoke(null, new object[] { dc, newExpression });
|
||||
.Invoke(null, new object[] { dc, newExpression })!;
|
||||
|
||||
if (prev != null)
|
||||
result = prev(result);
|
||||
|
@ -78,7 +79,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
return true;
|
||||
}
|
||||
|
||||
static ILinqToDBForEFTools _implementation = null!;
|
||||
static ILinqToDBForEFTools _implementation;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets EF Core to LINQ To DB integration bridge implementation.
|
||||
|
@ -86,6 +87,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
public static ILinqToDBForEFTools Implementation
|
||||
{
|
||||
get => _implementation;
|
||||
[MemberNotNull(nameof(_implementation), nameof(_defaultMetadataReader))]
|
||||
set
|
||||
{
|
||||
_implementation = value ?? throw new ArgumentNullException(nameof(value));
|
||||
|
@ -96,7 +98,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
|
||||
static readonly ConcurrentDictionary<IModel, IMetadataReader?> _metadataReaders = new();
|
||||
|
||||
static Lazy<IMetadataReader?> _defaultMetadataReader = null!;
|
||||
static Lazy<IMetadataReader?> _defaultMetadataReader;
|
||||
|
||||
/// <summary>
|
||||
/// Clears internal caches
|
||||
|
|
|
@ -131,7 +131,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
return _transformFunc(expression, this, Context, _model);
|
||||
}
|
||||
|
||||
private class TypeKey
|
||||
private sealed class TypeKey
|
||||
{
|
||||
public TypeKey(IEntityType entityType, IModel? model)
|
||||
{
|
||||
|
@ -142,7 +142,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
public IEntityType EntityType { get; }
|
||||
public IModel? Model { get; }
|
||||
|
||||
protected bool Equals(TypeKey other)
|
||||
private bool Equals(TypeKey other)
|
||||
{
|
||||
return EntityType.Equals(other.EntityType) && Equals(Model, other.Model);
|
||||
}
|
||||
|
@ -205,9 +205,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
if (eventData.TableName != _lastEntityType.GetTableName())
|
||||
return entity;
|
||||
|
||||
if (_stateManager == null)
|
||||
_stateManager = Context.GetService<IStateManager>();
|
||||
|
||||
_stateManager ??= Context.GetService<IStateManager>();
|
||||
|
||||
// It is a real pain to register entity in change tracker
|
||||
//
|
||||
|
@ -226,10 +224,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
|
||||
entry = retrievalFunc(_stateManager, entity);
|
||||
|
||||
if (entry == null)
|
||||
{
|
||||
entry = _stateManager.StartTrackingFromQuery(_lastEntityType, entity, ValueBuffer.Empty);
|
||||
}
|
||||
entry ??= _stateManager.StartTrackingFromQuery(_lastEntityType, entity, ValueBuffer.Empty);
|
||||
|
||||
return entry.Entity;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,5 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
return expression;
|
||||
return _transformFunc(expression, this, _context, _model);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
/// <summary>
|
||||
/// Exception class for EF.Core to LINQ To DB integration issues.
|
||||
/// </summary>
|
||||
public class LinqToDBForEFToolsException : Exception
|
||||
public sealed class LinqToDBForEFToolsException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates new instance of exception.
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
[PublicAPI]
|
||||
public class LinqToDBForEFToolsImplDefault : ILinqToDBForEFTools
|
||||
{
|
||||
class ProviderKey
|
||||
sealed class ProviderKey
|
||||
{
|
||||
public ProviderKey(string? providerName, string? connectionString)
|
||||
{
|
||||
|
@ -59,7 +59,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
|
||||
#region Equality members
|
||||
|
||||
protected bool Equals(ProviderKey other)
|
||||
private bool Equals(ProviderKey other)
|
||||
{
|
||||
return string.Equals(ProviderName, other.ProviderName) && string.Equals(ConnectionString, other.ConnectionString);
|
||||
}
|
||||
|
@ -163,31 +163,44 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
|
||||
switch (provInfo.ProviderName)
|
||||
{
|
||||
case ProviderName.SqlServer:
|
||||
return CreateSqlServerProvider(SqlServerDefaultVersion, connectionInfo.ConnectionString);
|
||||
case ProviderName.MySql:
|
||||
case ProviderName.MySqlConnector:
|
||||
return MySqlTools.GetDataProvider(provInfo.ProviderName);
|
||||
case ProviderName.PostgreSQL:
|
||||
return CreatePostgreSqlProvider(PostgreSqlDefaultVersion, connectionInfo.ConnectionString);
|
||||
case ProviderName.SQLite:
|
||||
return SQLiteTools.GetDataProvider(provInfo.ProviderName);
|
||||
case ProviderName.Firebird:
|
||||
return FirebirdTools.GetDataProvider();
|
||||
case ProviderName.DB2:
|
||||
case ProviderName.DB2LUW:
|
||||
return DB2Tools.GetDataProvider(DB2Version.LUW);
|
||||
case ProviderName.DB2zOS:
|
||||
case ProviderName.SqlServer:
|
||||
return CreateSqlServerProvider(SqlServerDefaultVersion, connectionInfo.ConnectionString);
|
||||
case ProviderName.MySql:
|
||||
case ProviderName.MySqlConnector:
|
||||
return MySqlTools.GetDataProvider(provInfo.ProviderName);
|
||||
case ProviderName.PostgreSQL:
|
||||
return CreatePostgreSqlProvider(PostgreSqlDefaultVersion, connectionInfo.ConnectionString);
|
||||
case ProviderName.SQLite:
|
||||
return SQLiteTools.GetDataProvider(provInfo.ProviderName);
|
||||
case ProviderName.Firebird:
|
||||
return FirebirdTools.GetDataProvider();
|
||||
case ProviderName.DB2:
|
||||
case ProviderName.DB2LUW:
|
||||
return DB2Tools.GetDataProvider(DB2Version.LUW);
|
||||
case ProviderName.DB2zOS:
|
||||
return DB2Tools.GetDataProvider(DB2Version.zOS);
|
||||
case ProviderName.Oracle:
|
||||
return OracleTools.GetDataProvider(provInfo.ProviderName, version: OracleVersion.v11);
|
||||
case ProviderName.SqlCe:
|
||||
return SqlCeTools.GetDataProvider();
|
||||
//case ProviderName.Access:
|
||||
// return new AccessDataProvider();
|
||||
|
||||
default:
|
||||
throw new LinqToDBForEFToolsException($"Can not instantiate data provider '{provInfo.ProviderName}'.");
|
||||
case ProviderName.Oracle11Native:
|
||||
return OracleTools.GetDataProvider(OracleVersion.v11, OracleProvider.Native);
|
||||
case ProviderName.OracleNative:
|
||||
return OracleTools.GetDataProvider(OracleVersion.v12, OracleProvider.Native);
|
||||
case ProviderName.Oracle11Managed:
|
||||
return OracleTools.GetDataProvider(OracleVersion.v11, OracleProvider.Managed);
|
||||
case ProviderName.Oracle:
|
||||
case ProviderName.OracleManaged:
|
||||
return OracleTools.GetDataProvider(OracleVersion.v12, OracleProvider.Managed);
|
||||
case ProviderName.Oracle11Devart:
|
||||
return OracleTools.GetDataProvider(OracleVersion.v11, OracleProvider.Devart);
|
||||
case ProviderName.OracleDevart:
|
||||
return OracleTools.GetDataProvider( OracleVersion.v12, OracleProvider.Devart);
|
||||
|
||||
case ProviderName.SqlCe:
|
||||
return SqlCeTools.GetDataProvider();
|
||||
//case ProviderName.Access:
|
||||
// return new AccessDataProvider();
|
||||
|
||||
default:
|
||||
throw new LinqToDBForEFToolsException($"Can not instantiate data provider '{provInfo.ProviderName}'.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -323,9 +336,6 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
/// <returns>linq2db SQL Server provider instance.</returns>
|
||||
protected virtual IDataProvider CreateSqlServerProvider(SqlServerVersion version, string? connectionString)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(connectionString))
|
||||
return DataConnection.GetDataProvider("Microsoft.Data.SqlClient", connectionString)!;
|
||||
|
||||
return DataProvider.SqlServer.SqlServerTools.GetDataProvider(version, SqlServerProvider.MicrosoftDataSqlClient);
|
||||
}
|
||||
|
||||
|
@ -337,9 +347,6 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
/// <returns>linq2db PostgreSQL provider instance.</returns>
|
||||
protected virtual IDataProvider CreatePostgreSqlProvider(PostgreSQLVersion version, string? connectionString)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(connectionString))
|
||||
return DataConnection.GetDataProvider(ProviderName.PostgreSQL, connectionString)!;
|
||||
|
||||
return PostgreSQLTools.GetDataProvider(version);
|
||||
}
|
||||
|
||||
|
@ -493,7 +500,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
{
|
||||
e.SlidingExpiration = TimeSpan.FromHours(1);
|
||||
return CreateMappingSchema(model, metadataReader, convertorSelector);
|
||||
});
|
||||
})!;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -515,36 +522,27 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
static readonly MethodInfo IncludeMethodInfoString = MemberHelper.MethodOfGeneric<IQueryable<object>>(q => q.Include(string.Empty));
|
||||
|
||||
static readonly MethodInfo ThenIncludeMethodInfo =
|
||||
MemberHelper.MethodOfGeneric<IIncludableQueryable<object, object>>(q => q.ThenInclude<object, object, object>(null));
|
||||
MemberHelper.MethodOfGeneric<IIncludableQueryable<object, object>>(q => q.ThenInclude<object, object, object>(null!));
|
||||
|
||||
static readonly MethodInfo TagWithMethodInfo =
|
||||
MemberHelper.MethodOfGeneric<IQueryable<object>>(q => q.TagWith(string.Empty));
|
||||
|
||||
static readonly MethodInfo ThenIncludeEnumerableMethodInfo =
|
||||
MemberHelper.MethodOfGeneric<IIncludableQueryable<object, IEnumerable<object>>>(q => q.ThenInclude<object, object, object>(null));
|
||||
MemberHelper.MethodOfGeneric<IIncludableQueryable<object, IEnumerable<object>>>(q => q.ThenInclude<object, object, object>(null!));
|
||||
|
||||
static readonly MethodInfo AsNoTrackingMethodInfo = MemberHelper.MethodOfGeneric<IQueryable<object>>(q => q.AsNoTracking());
|
||||
|
||||
static readonly MethodInfo EFProperty = MemberHelper.MethodOfGeneric(() => EF.Property<object>(1, ""));
|
||||
|
||||
static readonly MethodInfo
|
||||
L2DBProperty = typeof(Sql).GetMethod(nameof(Sql.Property)).GetGenericMethodDefinition();
|
||||
|
||||
static readonly MethodInfo L2DBFromSqlMethodInfo =
|
||||
MemberHelper.MethodOfGeneric<IDataContext>(dc => dc.FromSql<object>(new Common.RawSqlString()));
|
||||
|
||||
static readonly MethodInfo L2DBRemoveOrderByMethodInfo =
|
||||
MemberHelper.MethodOfGeneric<IQueryable<object>>(q => q.RemoveOrderBy());
|
||||
|
||||
static readonly ConstructorInfo RawSqlStringConstructor = MemberHelper.ConstructorOf(() => new Common.RawSqlString(""));
|
||||
|
||||
static readonly ConstructorInfo DataParameterConstructor = MemberHelper.ConstructorOf(() => new DataParameter("", "", DataType.Undefined, ""));
|
||||
|
||||
static readonly MethodInfo ToSql = MemberHelper.MethodOfGeneric(() => Sql.ToSql(1));
|
||||
|
||||
static readonly MethodInfo TagQueryMethodInfo =
|
||||
MemberHelper.MethodOfGeneric<IQueryable<object>>(q => q.TagQuery(string.Empty));
|
||||
|
||||
/// <summary>
|
||||
/// Removes conversions from expression.
|
||||
/// </summary>
|
||||
|
@ -842,7 +840,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
return new TransformInfo(Expression.Call(method, methodCall.Arguments.Select(a => a.Transform(l => LocalTransform(l)))
|
||||
.ToArray()), false, true);
|
||||
}
|
||||
else if (generic == L2DBRemoveOrderByMethodInfo)
|
||||
else if (generic == Methods.LinqToDB.RemoveOrderBy)
|
||||
{
|
||||
// This is workaround. EagerLoading runs query again with RemoveOrderBy method.
|
||||
// it is only one possible way now how to detect nested query.
|
||||
|
@ -850,8 +848,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
}
|
||||
else if (generic == TagWithMethodInfo)
|
||||
{
|
||||
var method =
|
||||
TagQueryMethodInfo.MakeGenericMethod(methodCall.Method.GetGenericArguments());
|
||||
var method = Methods.LinqToDB.TagQuery.MakeGenericMethod(methodCall.Method.GetGenericArguments());
|
||||
|
||||
return new TransformInfo(Expression.Call(method, methodCall.Arguments.Select(a => a.Transform(l => LocalTransform(l)))
|
||||
.ToArray()), false, true);
|
||||
|
@ -893,7 +890,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
|
||||
if (generic == EFProperty)
|
||||
{
|
||||
var prop = Expression.Call(null, L2DBProperty.MakeGenericMethod(methodCall.Method.GetGenericArguments()[0]),
|
||||
var prop = Expression.Call(null, Methods.LinqToDB.SqlExt.Property.MakeGenericMethod(methodCall.Method.GetGenericArguments()[0]),
|
||||
methodCall.Arguments[0], methodCall.Arguments[1]);
|
||||
return new TransformInfo(prop, false, true);
|
||||
}
|
||||
|
@ -919,16 +916,13 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
.FirstOrDefault();
|
||||
if (notParametrized != null)
|
||||
{
|
||||
if (newArguments == null)
|
||||
{
|
||||
newArguments = new List<Expression>(methodCall.Arguments.Take(i));
|
||||
}
|
||||
newArguments ??= new List<Expression>(methodCall.Arguments.Take(i));
|
||||
|
||||
newArguments.Add(Expression.Call(ToSql.MakeGenericMethod(arg.Type), arg));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
newArguments?.Add(methodCall.Arguments[i]);
|
||||
}
|
||||
|
||||
|
@ -949,13 +943,12 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
Expression.New(RawSqlStringConstructor, Expression.Constant(fromSqlQueryRoot.Sql)),
|
||||
fromSqlQueryRoot.Argument));
|
||||
}
|
||||
else if (dc != null && e is QueryRootExpression queryRoot)
|
||||
else if (dc != null && e is EntityQueryRootExpression queryRoot)
|
||||
{
|
||||
var newExpr = Expression.Call(null, Methods.LinqToDB.GetTable.MakeGenericMethod(queryRoot.EntityType.ClrType), Expression.Constant(dc));
|
||||
return new TransformInfo(newExpr);
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -964,7 +957,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
return new TransformInfo(e);
|
||||
}
|
||||
|
||||
var newExpression = expression.Transform(e => LocalTransform(e));
|
||||
var newExpression = expression.Transform(LocalTransform);
|
||||
|
||||
if (!ignoreTracking && dc is LinqToDBForEFToolsDataConnection dataConnection)
|
||||
{
|
||||
|
@ -997,7 +990,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
if (!IsEnumerableType(type, mappingSchema))
|
||||
return type;
|
||||
if (type.IsArray)
|
||||
return type.GetElementType();
|
||||
return type.GetElementType()!;
|
||||
if (typeof(IGrouping<,>).IsSameOrParentOf(type))
|
||||
return type.GetGenericArguments()[1];
|
||||
return type.GetGenericArguments()[0];
|
||||
|
@ -1020,8 +1013,8 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
/// <returns>Current <see cref="DbContext"/> instance.</returns>
|
||||
public virtual DbContext? GetCurrentContext(IQueryable query)
|
||||
{
|
||||
var compilerField = typeof (EntityQueryProvider).GetField("_queryCompiler", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
var compiler = (QueryCompiler) compilerField.GetValue(query.Provider);
|
||||
var compilerField = typeof (EntityQueryProvider).GetField("_queryCompiler", BindingFlags.NonPublic | BindingFlags.Instance)!;
|
||||
var compiler = (QueryCompiler)compilerField.GetValue(query.Provider)!;
|
||||
|
||||
var queryContextFactoryField = compiler.GetType().GetField("_queryContextFactory", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
|
@ -1031,12 +1024,12 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
if (queryContextFactoryField.GetValue(compiler) is not RelationalQueryContextFactory queryContextFactory)
|
||||
throw new LinqToDBForEFToolsException("LinqToDB Tools for EFCore support only Relational Databases.");
|
||||
|
||||
var dependenciesProperty = typeof(RelationalQueryContextFactory).GetField("_dependencies", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
var dependenciesProperty = typeof(RelationalQueryContextFactory).GetProperty("Dependencies", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
if (dependenciesProperty == null)
|
||||
throw new LinqToDBForEFToolsException($"Can not find private property '{nameof(RelationalQueryContextFactory)}._dependencies' in current EFCore Version.");
|
||||
throw new LinqToDBForEFToolsException($"Can not find protected property '{nameof(RelationalQueryContextFactory)}.Dependencies' in current EFCore Version.");
|
||||
|
||||
var dependencies = (QueryContextDependencies) dependenciesProperty.GetValue(queryContextFactory);
|
||||
var dependencies = (QueryContextDependencies)dependenciesProperty.GetValue(queryContextFactory)!;
|
||||
|
||||
return dependencies.CurrentContext?.Context;
|
||||
}
|
||||
|
@ -1074,7 +1067,6 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
/// <param name="logger">Logger instance.</param>
|
||||
public virtual void LogConnectionTrace(TraceInfo info, ILogger logger)
|
||||
{
|
||||
#pragma warning disable CA1848 // Use the LoggerMessage delegates
|
||||
var logLevel = info.TraceLevel switch
|
||||
{
|
||||
TraceLevel.Off => LogLevel.None,
|
||||
|
@ -1085,6 +1077,7 @@ namespace LinqToDB.EntityFrameworkCore
|
|||
_ => LogLevel.Trace,
|
||||
};
|
||||
|
||||
#pragma warning disable CA1848 // Use the LoggerMessage delegates
|
||||
using var _ = logger.BeginScope("TraceInfoStep: {TraceInfoStep}, IsAsync: {IsAsync}", info.TraceInfoStep, info.IsAsync);
|
||||
|
||||
switch (info.TraceInfoStep)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/// <summary>
|
||||
/// Stores LINQ To DB database provider information.
|
||||
/// </summary>
|
||||
public class LinqToDBProviderInfo
|
||||
public sealed class LinqToDBProviderInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Server version. Currently is not used.
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
|
||||
#pragma warning disable 1591
|
||||
// ReSharper disable UnusedMember.Global
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
<Title>Linq to DB (linq2db) extensions for Entity Framework Core</Title>
|
||||
<AssemblyTitle>$(Title)</AssemblyTitle>
|
||||
|
||||
<TargetFrameworks>netstandard2.1</TargetFrameworks>
|
||||
<RootNamespace>LinqToDB.EntityFrameworkCore</RootNamespace>
|
||||
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\linq2db.EntityFrameworkCore.xml</DocumentationFile>
|
||||
|
||||
|
|
|
@ -109,12 +109,12 @@ namespace LinqToDB.EntityFrameworkCore.BaseTests
|
|||
}
|
||||
|
||||
[Test]
|
||||
public virtual async Task TestAmbiguousProperties()
|
||||
public virtual void TestAmbiguousProperties()
|
||||
{
|
||||
using var context = CreateContext();
|
||||
|
||||
await FluentActions.Awaiting(() => context.WithDuplicateProperties.Where(x => x.Value == 1)
|
||||
.ToArrayAsyncLinqToDB()).Should().NotThrowAsync();
|
||||
FluentActions.Invoking(() => context.WithDuplicateProperties.Where(x => x.Value == 1)
|
||||
.ToArray()).Should().NotThrow();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging
|
|||
/// <summary>
|
||||
/// Scope provider that does nothing.
|
||||
/// </summary>
|
||||
internal class NullExternalScopeProvider : IExternalScopeProvider
|
||||
internal sealed class NullExternalScopeProvider : IExternalScopeProvider
|
||||
{
|
||||
private NullExternalScopeProvider()
|
||||
{
|
||||
|
@ -18,12 +18,12 @@ namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging
|
|||
public static IExternalScopeProvider Instance { get; } = new NullExternalScopeProvider();
|
||||
|
||||
/// <inheritdoc />
|
||||
void IExternalScopeProvider.ForEachScope<TState>(Action<object, TState> callback, TState state)
|
||||
void IExternalScopeProvider.ForEachScope<TState>(Action<object?, TState> callback, TState state)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
IDisposable IExternalScopeProvider.Push(object state)
|
||||
IDisposable IExternalScopeProvider.Push(object? state)
|
||||
{
|
||||
return NullScope.Instance;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging
|
||||
{
|
||||
internal class NullScope : IDisposable
|
||||
internal sealed class NullScope : IDisposable
|
||||
{
|
||||
public static NullScope Instance { get; } = new NullScope();
|
||||
|
||||
|
|
|
@ -6,16 +6,13 @@ using Microsoft.Extensions.Logging.Console;
|
|||
|
||||
namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging
|
||||
{
|
||||
internal class TestLogger : ILogger
|
||||
internal sealed class TestLogger : ILogger
|
||||
{
|
||||
private static readonly string _loglevelPadding = ": ";
|
||||
private static readonly string _messagePadding;
|
||||
private static readonly string _newLineWithMessagePadding;
|
||||
|
||||
// ConsoleColor does not have a value to specify the 'Default' color
|
||||
#pragma warning disable 649
|
||||
private readonly ConsoleColor? DefaultConsoleColor;
|
||||
#pragma warning restore 649
|
||||
private readonly ConsoleColor DefaultConsoleColor = ConsoleColor.Black;
|
||||
|
||||
private readonly string _name;
|
||||
|
||||
|
@ -38,7 +35,7 @@ namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging
|
|||
|
||||
internal ConsoleLoggerOptions? Options { get; set; }
|
||||
|
||||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
|
||||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
|
||||
{
|
||||
if (!IsEnabled(logLevel))
|
||||
{
|
||||
|
@ -58,18 +55,15 @@ namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging
|
|||
}
|
||||
}
|
||||
|
||||
public virtual void WriteMessage(LogLevel logLevel, string logName, int eventId, string message, Exception exception)
|
||||
public void WriteMessage(LogLevel logLevel, string logName, int eventId, string message, Exception? exception)
|
||||
{
|
||||
var format = Options!.FormatterName;
|
||||
var format = Options?.FormatterName;
|
||||
Debug.Assert(format is ConsoleFormatterNames.Simple or ConsoleFormatterNames.Systemd);
|
||||
|
||||
var logBuilder = _logBuilder;
|
||||
_logBuilder = null;
|
||||
|
||||
if (logBuilder == null)
|
||||
{
|
||||
logBuilder = new StringBuilder();
|
||||
}
|
||||
logBuilder ??= new StringBuilder();
|
||||
|
||||
LogMessageEntry entry;
|
||||
if (format == ConsoleFormatterNames.Simple)
|
||||
|
@ -99,7 +93,7 @@ namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging
|
|||
WriteMessage(entry);
|
||||
}
|
||||
|
||||
internal virtual void WriteMessage(LogMessageEntry message)
|
||||
internal void WriteMessage(LogMessageEntry message)
|
||||
{
|
||||
if (message.TimeStamp != null)
|
||||
{
|
||||
|
@ -114,7 +108,7 @@ namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging
|
|||
Console.WriteLine(message.Message);
|
||||
}
|
||||
|
||||
private LogMessageEntry CreateDefaultLogMessage(StringBuilder logBuilder, LogLevel logLevel, string logName, int eventId, string message, Exception exception)
|
||||
private LogMessageEntry CreateDefaultLogMessage(StringBuilder logBuilder, LogLevel logLevel, string logName, int eventId, string message, Exception? exception)
|
||||
{
|
||||
// Example:
|
||||
// INFO: ConsoleApp.Program[10]
|
||||
|
@ -152,7 +146,7 @@ namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging
|
|||
}
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
var timestampFormat = Options!.TimestampFormat;
|
||||
var timestampFormat = Options?.TimestampFormat;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
||||
return new LogMessageEntry(
|
||||
|
@ -162,11 +156,11 @@ namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging
|
|||
levelBackground: logLevelColors.Background,
|
||||
levelForeground: logLevelColors.Foreground,
|
||||
messageColor: DefaultConsoleColor,
|
||||
logAsError: logLevel >= Options!.LogToStandardErrorThreshold
|
||||
logAsError: logLevel >= Options?.LogToStandardErrorThreshold
|
||||
);
|
||||
}
|
||||
|
||||
private LogMessageEntry CreateSystemdLogMessage(StringBuilder logBuilder, LogLevel logLevel, string logName, int eventId, string message, Exception exception)
|
||||
private LogMessageEntry CreateSystemdLogMessage(StringBuilder logBuilder, LogLevel logLevel, string logName, int eventId, string message, Exception? exception)
|
||||
{
|
||||
// systemd reads messages from standard out line-by-line in a '<pri>message' format.
|
||||
// newline characters are treated as message delimiters, so we must replace them.
|
||||
|
@ -180,7 +174,7 @@ namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging
|
|||
|
||||
// timestamp
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
var timestampFormat = Options!.TimestampFormat;
|
||||
var timestampFormat = Options?.TimestampFormat;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
if (timestampFormat != null)
|
||||
{
|
||||
|
@ -217,7 +211,7 @@ namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging
|
|||
|
||||
return new LogMessageEntry(
|
||||
message: logBuilder.ToString(),
|
||||
logAsError: logLevel >= Options.LogToStandardErrorThreshold
|
||||
logAsError: logLevel >= Options?.LogToStandardErrorThreshold
|
||||
);
|
||||
|
||||
static void AppendAndReplaceNewLine(StringBuilder sb, string message)
|
||||
|
@ -233,7 +227,9 @@ namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging
|
|||
return logLevel != LogLevel.None;
|
||||
}
|
||||
|
||||
public IDisposable BeginScope<TState>(TState state) => ScopeProvider?.Push(state) ?? NullScope.Instance;
|
||||
public IDisposable BeginScope<TState>(TState state)
|
||||
where TState : notnull
|
||||
=> ScopeProvider?.Push(state) ?? NullScope.Instance;
|
||||
|
||||
private static string GetLogLevelString(LogLevel logLevel)
|
||||
{
|
||||
|
@ -280,7 +276,7 @@ namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging
|
|||
private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel)
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
if (Options!.DisableColors)
|
||||
if (Options?.DisableColors == true)
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
{
|
||||
return new ConsoleColors(null, null);
|
||||
|
@ -311,7 +307,7 @@ namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging
|
|||
{
|
||||
var scopeProvider = ScopeProvider;
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
if (Options!.IncludeScopes && scopeProvider != null)
|
||||
if (Options?.IncludeScopes == true && scopeProvider != null)
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
{
|
||||
var initialLength = stringBuilder.Length;
|
||||
|
@ -352,5 +348,4 @@ namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging
|
|||
public ConsoleColor? Background { get; }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace LinqToDB.EntityFrameworkCore.BaseTests.Logging
|
|||
private readonly IOptionsMonitor<ConsoleLoggerOptions> _options;
|
||||
private readonly ConcurrentDictionary<string, TestLogger> _loggers;
|
||||
|
||||
private readonly IDisposable _optionsReloadToken;
|
||||
private readonly IDisposable? _optionsReloadToken;
|
||||
private IExternalScopeProvider _scopeProvider = NullExternalScopeProvider.Instance;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -130,7 +130,7 @@ namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind
|
|||
{
|
||||
context.Set<Customer>().AddRange(CreateCustomers());
|
||||
|
||||
var titleProperty = context.Model.FindEntityType(typeof(Employee)).FindProperty("Title");
|
||||
var titleProperty = context.Model.FindEntityType(typeof(Employee))!.FindProperty("Title")!;
|
||||
foreach (var employee in CreateEmployees())
|
||||
{
|
||||
context.Set<Employee>().Add(employee);
|
||||
|
@ -147,7 +147,7 @@ namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind
|
|||
context.Set<OrderDetail>().AddRange(CreateOrderDetails());
|
||||
}
|
||||
|
||||
private class AsyncEnumerable<T> : IAsyncQueryProvider, IOrderedQueryable<T>
|
||||
private sealed class AsyncEnumerable<T> : IAsyncQueryProvider, IOrderedQueryable<T>
|
||||
{
|
||||
private readonly EnumerableQuery<T> _enumerableQuery;
|
||||
|
||||
|
@ -178,7 +178,7 @@ namespace LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind
|
|||
private static Expression RewriteShadowPropertyAccess(Expression expression)
|
||||
=> new ShadowStateAccessRewriter().Visit(expression);
|
||||
|
||||
private class ShadowStateAccessRewriter : ExpressionVisitor
|
||||
private sealed class ShadowStateAccessRewriter : ExpressionVisitor
|
||||
{
|
||||
[return: NotNullIfNotNull("expr")]
|
||||
static Expression? RemoveConvert(Expression? expr)
|
||||
|
|
|
@ -12,9 +12,9 @@ namespace LinqToDB.EntityFrameworkCore.PomeloMySql.Tests
|
|||
public override ForMappingContextBase CreateContext()
|
||||
{
|
||||
var optionsBuilder = new DbContextOptionsBuilder<ForMappingContext>();
|
||||
optionsBuilder.UseMySql(
|
||||
"Server=DBHost;Port=3306;Database=TestData;Uid=TestUser;Pwd=TestPassword;charset=utf8;",
|
||||
ServerVersion.AutoDetect("Server=DBHost;Port=3306;Database=TestData;Uid=TestUser;Pwd=TestPassword;charset=utf8;"));
|
||||
var connectionString = "Server=DBHost;Port=3306;Database=TestData;Uid=TestUser;Pwd=TestPassword;charset=utf8;";
|
||||
//var connectionString = "Server=localhost;Port=3316;Database=TestData;Uid=root;Pwd=root;charset=utf8;";
|
||||
optionsBuilder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString));
|
||||
optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory);
|
||||
|
||||
var options = optionsBuilder.Options;
|
||||
|
|
|
@ -3,13 +3,17 @@
|
|||
<Import Project="..\..\Build\linq2db.Tests.props" />
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Models\UniversalEntities\**" />
|
||||
<EmbeddedResource Remove="Models\UniversalEntities\**" />
|
||||
<None Remove="Models\UniversalEntities\**" />
|
||||
<Compile Remove="Models\UniversalEntities\**" />
|
||||
<EmbeddedResource Remove="Models\UniversalEntities\**" />
|
||||
<None Remove="Models\UniversalEntities\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" />
|
||||
<!--TODO: remove after v7 release-->
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational">
|
||||
<NoWarn>NU1107;NU1608</NoWarn>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping
|
|||
builder.Property(e => e.TitleOfCourtesy).HasMaxLength(25);
|
||||
|
||||
builder.HasOne(d => d.ReportsToNavigation)
|
||||
.WithMany(p => p!.InverseReportsToNavigation)
|
||||
.WithMany(p => p.InverseReportsToNavigation)
|
||||
.HasForeignKey(d => d.ReportsTo)
|
||||
.HasConstraintName("FK_Employees_Employees");
|
||||
}
|
||||
|
|
|
@ -61,17 +61,17 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping
|
|||
builder.Property(e => e.ShippedDate).HasColumnType("datetime");
|
||||
|
||||
builder.HasOne(d => d.Customer)
|
||||
.WithMany(p => p!.Orders)
|
||||
.WithMany(p => p.Orders)
|
||||
.HasForeignKey(d => d.CustomerId)
|
||||
.HasConstraintName("FK_Orders_Customers");
|
||||
|
||||
builder.HasOne(d => d.Employee)
|
||||
.WithMany(p => p!.Orders)
|
||||
.WithMany(p => p.Orders)
|
||||
.HasForeignKey(d => d.EmployeeId)
|
||||
.HasConstraintName("FK_Orders_Employees");
|
||||
|
||||
builder.HasOne(d => d.ShipViaNavigation)
|
||||
.WithMany(p => p!.Orders)
|
||||
.WithMany(p => p.Orders)
|
||||
.HasForeignKey(d => d.ShipVia)
|
||||
.HasConstraintName("FK_Orders_Shippers");
|
||||
}
|
||||
|
|
|
@ -43,12 +43,12 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping
|
|||
builder.Property(e => e.UnitsOnOrder).HasDefaultValue((short)0);
|
||||
|
||||
builder.HasOne(d => d.Category)
|
||||
.WithMany(p => p!.Products)
|
||||
.WithMany(p => p.Products)
|
||||
.HasForeignKey(d => d.CategoryId)
|
||||
.HasConstraintName("FK_Products_Categories");
|
||||
|
||||
builder.HasOne(d => d.Supplier)
|
||||
.WithMany(p => p!.Products)
|
||||
.WithMany(p => p.Products)
|
||||
.HasForeignKey(d => d.SupplierId)
|
||||
.HasConstraintName("FK_Products_Suppliers");
|
||||
}
|
||||
|
|
|
@ -22,9 +22,9 @@ namespace LinqToDB.EntityFrameworkCore.PomeloMySql.Tests
|
|||
var optionsBuilder = new DbContextOptionsBuilder<NorthwindContext>();
|
||||
//new SqlServerDbContextOptionsBuilder(optionsBuilder);
|
||||
|
||||
optionsBuilder.UseMySql(
|
||||
"Server=DBHost;Port=3306;Database=TestData;Uid=TestUser;Pwd=TestPassword;charset=utf8;",
|
||||
ServerVersion.AutoDetect("Server=DBHost;Port=3306;Database=TestData;Uid=TestUser;Pwd=TestPassword;charset=utf8;"));
|
||||
var connectionString = "Server=DBHost;Port=3306;Database=TestData;Uid=TestUser;Pwd=TestPassword;charset=utf8;";
|
||||
//var connectionString = "Server=localhost;Port=3316;Database=TestData;Uid=root;Pwd=root;charset=utf8;";
|
||||
optionsBuilder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString));
|
||||
|
||||
optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory);
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests
|
|||
{
|
||||
var optionsBuilder = new DbContextOptionsBuilder<ForMappingContext>();
|
||||
optionsBuilder.UseNpgsql("Server=DBHost;Port=5432;Database=ForMapping;User Id=postgres;Password=TestPassword;Pooling=true;MinPoolSize=10;MaxPoolSize=100;");
|
||||
//optionsBuilder.UseNpgsql("Server=localhost;Port=5415;Database=ForMapping;User Id=postgres;Password=Password12!;Pooling=true;MinPoolSize=10;MaxPoolSize=100;");
|
||||
optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory);
|
||||
|
||||
var options = optionsBuilder.Options;
|
||||
|
|
|
@ -5,10 +5,8 @@ namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.Models.ForMapping
|
|||
{
|
||||
public class ForMappingContext : ForMappingContextBase
|
||||
{
|
||||
|
||||
public ForMappingContext(DbContextOptions options) : base(options)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.Models.NpgSqlEntities
|
||||
{
|
||||
|
|
|
@ -5,8 +5,8 @@ namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.Models.NpgSqlEntities
|
|||
{
|
||||
public class Event
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = null!;
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = null!;
|
||||
public NpgsqlRange<DateTime> Duration { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.Models.NpgSqlEntities
|
|||
|
||||
modelBuilder.Entity<EntityWithXmin>(entity =>
|
||||
{
|
||||
entity.UseXminAsConcurrencyToken();
|
||||
entity.Property<uint>(nameof(NpgSqlEntities.EntityWithXmin.xmin)).IsRowVersion();
|
||||
});
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests
|
|||
//new SqlServerDbContextOptionsBuilder(optionsBuilder);
|
||||
|
||||
optionsBuilder.UseNpgsql("Server=DBHost;Port=5432;Database=TestData;User Id=postgres;Password=TestPassword;Pooling=true;MinPoolSize=10;MaxPoolSize=100;");
|
||||
//optionsBuilder.UseNpgsql("Server=localhost;Port=5415;Database=TestData;User Id=postgres;Password=Password12!;Pooling=true;MinPoolSize=10;MaxPoolSize=100;");
|
||||
optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory);
|
||||
|
||||
_options = optionsBuilder.Options;
|
||||
|
|
|
@ -1,123 +1,119 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#pragma warning disable 8604
|
||||
#pragma warning disable CS8625
|
||||
|
||||
namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests
|
||||
{
|
||||
public class Unit
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static class ExceptionExtensions
|
||||
{
|
||||
public static Unit Throw(this Exception e) => throw e;
|
||||
}
|
||||
|
||||
public static class AAA
|
||||
{
|
||||
public static ArrangeResult<T, Unit> Arrange<T>(this T @object, Action<T> action)
|
||||
{
|
||||
action(@object);
|
||||
return new ArrangeResult<T, Unit>(@object, default);
|
||||
}
|
||||
|
||||
public static ArrangeResult<T, Unit> Arrange<T>(T @object)
|
||||
=> new(@object, default);
|
||||
|
||||
public static ArrangeResult<T, TMock> Arrange<T, TMock>(this TMock mock, Func<TMock, T> @object)
|
||||
where TMock: notnull
|
||||
=> new(@object(mock), mock);
|
||||
|
||||
public static ActResult<T, TMock> Act<T, TMock>(this ArrangeResult<T, TMock> arrange, Action<T> act)
|
||||
where T : notnull
|
||||
where TMock : notnull
|
||||
{
|
||||
try
|
||||
{
|
||||
act(arrange.Object);
|
||||
return new ActResult<T, TMock>(arrange.Object, arrange.Mock, default);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new ActResult<T, TMock>(arrange.Object, arrange.Mock, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static ActResult<TResult, TMock> Act<T, TMock, TResult>(this ArrangeResult<T, TMock> arrange, Func<T, TResult> act)
|
||||
where TResult : notnull
|
||||
where TMock : notnull
|
||||
{
|
||||
try
|
||||
{
|
||||
return new ActResult<TResult, TMock>(act(arrange.Object), arrange.Mock, default);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new ActResult<TResult, TMock>(default, arrange.Mock, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Assert<T, TMock>(this ActResult<T, TMock> act, Action<T> assert)
|
||||
where T : notnull
|
||||
where TMock : notnull
|
||||
{
|
||||
act.Exception?.Throw();
|
||||
assert(act.Object);
|
||||
}
|
||||
|
||||
public static void Assert<T, TMock>(this ActResult<T, TMock> act, Action<T, TMock> assert)
|
||||
where T : notnull
|
||||
where TMock : notnull
|
||||
{
|
||||
act.Exception?.Throw();
|
||||
assert(act.Object, act.Mock);
|
||||
}
|
||||
|
||||
public static Task<ArrangeResult<T, Unit>> ArrangeAsync<T>(T @object)
|
||||
=> Task.FromResult(new ArrangeResult<T, Unit>(@object, default));
|
||||
|
||||
public static async Task<ActResult<TResult, TMock>> Act<T, TMock, TResult>(this Task<ArrangeResult<T, TMock>> arrange, Func<T, Task<TResult>> act)
|
||||
where TMock : notnull
|
||||
where TResult : notnull
|
||||
{
|
||||
var a = await arrange;
|
||||
try
|
||||
{
|
||||
return new ActResult<TResult, TMock>(await act(a.Object), a.Mock, default);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new ActResult<TResult, TMock>(default, a.Mock, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task Assert<T, TMock>(this Task<ActResult<T, TMock>> act, Func<T, Task> assert)
|
||||
where T : notnull
|
||||
where TMock : notnull
|
||||
{
|
||||
var result = await act;
|
||||
await assert(result.Object);
|
||||
}
|
||||
|
||||
public readonly struct ArrangeResult<T, TMock>
|
||||
where TMock : notnull
|
||||
{
|
||||
internal ArrangeResult(T @object, TMock mock) => (Object, Mock) = (@object, mock);
|
||||
internal T Object { get; }
|
||||
internal TMock Mock { get; }
|
||||
}
|
||||
|
||||
public readonly struct ActResult<T, TMock>
|
||||
where T: notnull
|
||||
{
|
||||
internal ActResult(T @object, TMock mock, Exception? exception)
|
||||
=> (Object, Mock, Exception) = (@object, mock, exception);
|
||||
internal T Object { get; }
|
||||
internal TMock Mock { get; }
|
||||
internal Exception? Exception { get; }
|
||||
}
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests
|
||||
{
|
||||
public class Unit
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExceptionExtensions
|
||||
{
|
||||
public static Unit Throw(this Exception e) => throw e;
|
||||
}
|
||||
|
||||
public static class AAA
|
||||
{
|
||||
public static ArrangeResult<T, Unit> Arrange<T>(this T @object, Action<T> action)
|
||||
{
|
||||
action(@object);
|
||||
return new ArrangeResult<T, Unit>(@object, default);
|
||||
}
|
||||
|
||||
public static ArrangeResult<T, Unit> Arrange<T>(T @object)
|
||||
=> new(@object, default);
|
||||
|
||||
public static ArrangeResult<T, TMock> Arrange<T, TMock>(this TMock mock, Func<TMock, T> @object)
|
||||
where TMock: notnull
|
||||
=> new(@object(mock), mock);
|
||||
|
||||
public static ActResult<T, TMock> Act<T, TMock>(this ArrangeResult<T, TMock> arrange, Action<T> act)
|
||||
where T : notnull
|
||||
where TMock : notnull
|
||||
{
|
||||
try
|
||||
{
|
||||
act(arrange.Object);
|
||||
return new ActResult<T, TMock>(arrange.Object, arrange.Mock, default);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new ActResult<T, TMock>(arrange.Object, arrange.Mock, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static ActResult<TResult, TMock> Act<T, TMock, TResult>(this ArrangeResult<T, TMock> arrange, Func<T, TResult> act)
|
||||
where TResult : notnull
|
||||
where TMock : notnull
|
||||
{
|
||||
try
|
||||
{
|
||||
return new ActResult<TResult, TMock>(act(arrange.Object), arrange.Mock, default);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new ActResult<TResult, TMock>(default, arrange.Mock, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Assert<T, TMock>(this ActResult<T, TMock> act, Action<T?> assert)
|
||||
where T : notnull
|
||||
where TMock : notnull
|
||||
{
|
||||
act.Exception?.Throw();
|
||||
assert(act.Object);
|
||||
}
|
||||
|
||||
public static void Assert<T, TMock>(this ActResult<T, TMock> act, Action<T?, TMock?> assert)
|
||||
where T : notnull
|
||||
where TMock : notnull
|
||||
{
|
||||
act.Exception?.Throw();
|
||||
assert(act.Object, act.Mock);
|
||||
}
|
||||
|
||||
public static Task<ArrangeResult<T, Unit>> ArrangeAsync<T>(T @object)
|
||||
=> Task.FromResult(new ArrangeResult<T, Unit>(@object, default));
|
||||
|
||||
public static async Task<ActResult<TResult, TMock>> Act<T, TMock, TResult>(this Task<ArrangeResult<T, TMock>> arrange, Func<T, Task<TResult>> act)
|
||||
where TMock : notnull
|
||||
where TResult : notnull
|
||||
{
|
||||
var a = await arrange;
|
||||
try
|
||||
{
|
||||
return new ActResult<TResult, TMock>(await act(a.Object), a.Mock, default);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new ActResult<TResult, TMock>(default, a.Mock, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task Assert<T, TMock>(this Task<ActResult<T, TMock>> act, Func<T?, Task> assert)
|
||||
where T : notnull
|
||||
where TMock : notnull
|
||||
{
|
||||
var result = await act;
|
||||
await assert(result.Object);
|
||||
}
|
||||
|
||||
public readonly struct ArrangeResult<T, TMock>
|
||||
where TMock : notnull
|
||||
{
|
||||
internal ArrangeResult(T @object, TMock? mock) => (Object, Mock) = (@object, mock);
|
||||
internal T Object { get; }
|
||||
internal TMock? Mock { get; }
|
||||
}
|
||||
|
||||
public readonly struct ActResult<T, TMock>
|
||||
where T: notnull
|
||||
{
|
||||
internal ActResult(T? @object, TMock? mock, Exception? exception)
|
||||
=> (Object, Mock, Exception) = (@object, mock, exception);
|
||||
internal T? Object { get; }
|
||||
internal TMock? Mock { get; }
|
||||
internal Exception? Exception { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests
|
||||
{
|
||||
public static class DataContextExtensions
|
||||
{
|
||||
public static Id<T, long> Insert<T>(this IDataContext context, T item)
|
||||
where T : IHasWriteableId<T, long>
|
||||
{
|
||||
item.Id = context.InsertWithInt64Identity(item).AsId<T>();
|
||||
return item.Id;
|
||||
}
|
||||
}
|
||||
public static class DataContextExtensions
|
||||
{
|
||||
public static Id<T, long> Insert<T>(this IDataContext context, T item)
|
||||
where T : IHasWriteableId<T, long>
|
||||
{
|
||||
item.Id = context.InsertWithInt64Identity(item).AsId<T>();
|
||||
return item.Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests
|
||||
{
|
||||
public sealed class Entity2Item
|
||||
{
|
||||
public Id<Entity, long> EntityId { get; set; }
|
||||
public Entity Entity { get; set; } = null!;
|
||||
public sealed class Entity2Item
|
||||
{
|
||||
public Id<Entity, long> EntityId { get; set; }
|
||||
public Entity Entity { get; set; } = null!;
|
||||
public Id<Item, long> ItemId { get; set; }
|
||||
|
||||
public Entity2Item()
|
||||
{
|
||||
}
|
||||
public Entity2Item()
|
||||
{
|
||||
}
|
||||
|
||||
public Item Item { get; set; } = null!;
|
||||
public Item Item { get; set; } = null!;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests
|
||||
{
|
||||
public interface IHasId<T, TId>
|
||||
public interface IHasId<T, TId>
|
||||
where T: IHasId<T, TId>
|
||||
where TId : notnull
|
||||
{
|
||||
Id<T, TId> Id { get; }
|
||||
}
|
||||
|
||||
public interface IHasWriteableId<T, TId> : IHasId<T, TId>
|
||||
Id<T, TId> Id { get; }
|
||||
}
|
||||
|
||||
public interface IHasWriteableId<T, TId> : IHasId<T, TId>
|
||||
where T: IHasWriteableId<T, TId>
|
||||
where TId : notnull
|
||||
{
|
||||
new Id<T, TId> Id { get; set; }
|
||||
}
|
||||
new Id<T, TId> Id { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests
|
|||
public static Id<T, TId> AsId<T, TId>(this TId id)
|
||||
where T : IHasId<T, TId>
|
||||
where TId : notnull
|
||||
=> new Id<T, TId>(id);
|
||||
=> new(id);
|
||||
}
|
||||
|
||||
public readonly struct Id<T, TId>
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests
|
|||
.UseLoggerFactory(TestUtils.LoggerFactory)
|
||||
.EnableSensitiveDataLogging()
|
||||
.UseNpgsql("Server=DBHost;Port=5432;Database=IdTests;User Id=postgres;Password=TestPassword;Pooling=true;MinPoolSize=10;MaxPoolSize=100;")
|
||||
//.UseNpgsql("Server=localhost;Port=5415;Database=IdTests;User Id=postgres;Password=Password12!;Pooling=true;MinPoolSize=10;MaxPoolSize=100;")
|
||||
.Options);
|
||||
_efContext.Database.EnsureDeleted();
|
||||
_efContext.Database.EnsureCreated();
|
||||
|
@ -39,7 +40,7 @@ namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests
|
|||
[Ignore("Incomplete.")]
|
||||
public void TestInsertWithoutTracker([Values("test insert")] string name)
|
||||
=> _efContext
|
||||
.Arrange(c => CreateLinqToDbContext(c))
|
||||
.Arrange(CreateLinqToDbContext)
|
||||
.Act(c => c.Insert(new Entity { Name = name }))
|
||||
.Assert(id => _efContext.Entitites.Single(e => e.Id == id).Name.Should().Be(name));
|
||||
|
||||
|
@ -73,7 +74,7 @@ namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests
|
|||
.AsLinqToDb(l2db)
|
||||
.AsTracking(tracking)
|
||||
.ToArray())
|
||||
.Assert(e => e.First().Details.First().Details.Count().Should().Be(2));
|
||||
.Assert(e => e?.First().Details.First().Details.Count().Should().Be(2));
|
||||
|
||||
[Test]
|
||||
public void TestManyToManyIncludeTrackerPoison([Values] bool l2db)
|
||||
|
@ -102,7 +103,7 @@ namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests
|
|||
.AsLinqToDb(l2db)
|
||||
.AsTracking(tracking)
|
||||
.ToArray())
|
||||
.Assert(m => m[0].Items.First().Item.Should().BeSameAs(m[1].Items.First().Item));
|
||||
.Assert(m => m?[0].Items.First().Item.Should().BeSameAs(m[1].Items.First().Item));
|
||||
|
||||
[Test]
|
||||
[Ignore("Incomplete.")]
|
||||
|
@ -115,7 +116,7 @@ namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests
|
|||
.AsLinqToDb(l2db)
|
||||
.AsTracking(tracking)
|
||||
.ToArray())
|
||||
.Assert(m => m[0].Master.Should().BeSameAs(m[1].Master));
|
||||
.Assert(m => m?[0].Master.Should().BeSameAs(m[1].Master));
|
||||
|
||||
[Test]
|
||||
[Ignore("Incomplete.")]
|
||||
|
@ -128,7 +129,7 @@ namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests
|
|||
.AsTracking(tracking)
|
||||
.AsLinqToDb(l2db)
|
||||
.ToArray())
|
||||
.Assert(m => m[0].Master.Should().BeSameAs(m[1].Master));
|
||||
.Assert(m => m?[0].Master.Should().BeSameAs(m[1].Master));
|
||||
|
||||
void InsertDefaults(IDataContext dataContext)
|
||||
{
|
||||
|
|
|
@ -98,25 +98,25 @@ namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests
|
|||
|
||||
public static ModelBuilder UseSnakeCase(this ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Model.SetDefaultSchema(modelBuilder.Model.GetDefaultSchema().ToSnakeCase());
|
||||
modelBuilder.Model.SetDefaultSchema(modelBuilder.Model.GetDefaultSchema()?.ToSnakeCase());
|
||||
foreach (var entity in modelBuilder.Model.GetEntityTypes())
|
||||
{
|
||||
entity.SetTableName(entity.GetTableName().ToSnakeCase());
|
||||
var storeObjectId = StoreObjectIdentifier.Create(entity, StoreObjectType.Table);
|
||||
entity.SetTableName(entity.GetTableName()?.ToSnakeCase());
|
||||
var storeObjectId = StoreObjectIdentifier.Create(entity, StoreObjectType.Table)!;
|
||||
|
||||
foreach (var property in entity.GetProperties())
|
||||
{
|
||||
property.SetColumnName(property.GetColumnName(storeObjectId!.Value).ToSnakeCase());
|
||||
property.SetColumnName(property.GetColumnName(storeObjectId.Value)?.ToSnakeCase());
|
||||
}
|
||||
|
||||
foreach (var key in entity.GetKeys())
|
||||
key.SetName(key.GetName().ToSnakeCase());
|
||||
foreach (var key in entity.GetKeys())
|
||||
key.SetName(key.GetName()?.ToSnakeCase());
|
||||
|
||||
foreach (var key in entity.GetForeignKeys())
|
||||
key.SetConstraintName(key.GetConstraintName().ToSnakeCase());
|
||||
foreach (var key in entity.GetForeignKeys())
|
||||
key.SetConstraintName(key.GetConstraintName()?.ToSnakeCase());
|
||||
|
||||
foreach (var index in entity.GetIndexes())
|
||||
index.SetDatabaseName(index.GetDatabaseName().ToSnakeCase());
|
||||
foreach (var index in entity.GetIndexes())
|
||||
index.SetDatabaseName(index.GetDatabaseName()?.ToSnakeCase());
|
||||
}
|
||||
return modelBuilder;
|
||||
}
|
||||
|
|
|
@ -2,15 +2,26 @@
|
|||
|
||||
namespace LinqToDB.EntityFrameworkCore.PostgreSQL.Tests.SampleTests
|
||||
{
|
||||
public static class StringExtensions
|
||||
{
|
||||
public static string ToSnakeCase(this string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
return input;
|
||||
public static partial class StringExtensions
|
||||
{
|
||||
public static string ToSnakeCase(this string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
return input;
|
||||
|
||||
var startUnderscores = Regex.Match(input, @"^_+");
|
||||
return startUnderscores + Regex.Replace(input, @"([a-z0-9])([A-Z])", "$1_$2").ToLower();
|
||||
}
|
||||
}
|
||||
var startUnderscores = UnderscoresMatcher.Match(input);
|
||||
return startUnderscores + Replacer.Replace(input, "$1_$2").ToLowerInvariant();
|
||||
}
|
||||
|
||||
// TODO: uncomment after azure pipelines updated to 17.4
|
||||
//[GeneratedRegex("^_+")]
|
||||
//private static partial Regex UnderscoresMatcher();
|
||||
//[GeneratedRegex("([a-z0-9])([A-Z])")]
|
||||
//private static partial Regex Replacer();
|
||||
|
||||
#pragma warning disable SYSLIB1045 // Convert to 'GeneratedRegexAttribute'.
|
||||
private static readonly Regex UnderscoresMatcher = new ("^_+", RegexOptions.Compiled);
|
||||
private static readonly Regex Replacer = new ("([a-z0-9])([A-Z])", RegexOptions.Compiled);
|
||||
#pragma warning restore SYSLIB1045 // Convert to 'GeneratedRegexAttribute'.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,10 +5,8 @@ namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.ForMapping
|
|||
{
|
||||
public class ForMappingContext : ForMappingContextBase
|
||||
{
|
||||
|
||||
public ForMappingContext(DbContextOptions options) : base(options)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
|
|
|
@ -8,7 +8,6 @@ namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping
|
|||
{
|
||||
public void Configure(EntityTypeBuilder<Category> builder)
|
||||
{
|
||||
|
||||
builder.HasKey(e => e.CategoryId);
|
||||
|
||||
builder.HasIndex(e => e.CategoryName)
|
||||
|
|
|
@ -4,33 +4,31 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|||
|
||||
namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping
|
||||
{
|
||||
public class CustomerCustomerDemoMap : IEntityTypeConfiguration<CustomerCustomerDemo>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<CustomerCustomerDemo> builder)
|
||||
{
|
||||
|
||||
builder.HasKey(e => new { e.CustomerId, e.CustomerTypeId });
|
||||
public class CustomerCustomerDemoMap : IEntityTypeConfiguration<CustomerCustomerDemo>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<CustomerCustomerDemo> builder)
|
||||
{
|
||||
builder.HasKey(e => new { e.CustomerId, e.CustomerTypeId });
|
||||
|
||||
builder.Property(e => e.CustomerId)
|
||||
.HasColumnName("CustomerID")
|
||||
.HasMaxLength(5);
|
||||
builder.Property(e => e.CustomerId)
|
||||
.HasColumnName("CustomerID")
|
||||
.HasMaxLength(5);
|
||||
|
||||
builder.Property(e => e.CustomerTypeId)
|
||||
.HasColumnName("CustomerTypeID")
|
||||
.HasMaxLength(10);
|
||||
builder.Property(e => e.CustomerTypeId)
|
||||
.HasColumnName("CustomerTypeID")
|
||||
.HasMaxLength(10);
|
||||
|
||||
builder.HasOne(d => d.Customer)
|
||||
.WithMany(p => p.CustomerCustomerDemo)
|
||||
.HasForeignKey(d => d.CustomerId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_CustomerCustomerDemo_Customers");
|
||||
builder.HasOne(d => d.Customer)
|
||||
.WithMany(p => p.CustomerCustomerDemo)
|
||||
.HasForeignKey(d => d.CustomerId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_CustomerCustomerDemo_Customers");
|
||||
|
||||
builder.HasOne(d => d.CustomerType)
|
||||
.WithMany(p => p.CustomerCustomerDemo)
|
||||
.HasForeignKey(d => d.CustomerTypeId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_CustomerCustomerDemo");
|
||||
|
||||
}
|
||||
}
|
||||
builder.HasOne(d => d.CustomerType)
|
||||
.WithMany(p => p.CustomerCustomerDemo)
|
||||
.HasForeignKey(d => d.CustomerTypeId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_CustomerCustomerDemo");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,18 +4,18 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|||
|
||||
namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping
|
||||
{
|
||||
public class CustomerDemographicsMap : IEntityTypeConfiguration<CustomerDemographics>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<CustomerDemographics> builder)
|
||||
{
|
||||
builder.HasKey(e => e.CustomerTypeId);
|
||||
public class CustomerDemographicsMap : IEntityTypeConfiguration<CustomerDemographics>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<CustomerDemographics> builder)
|
||||
{
|
||||
builder.HasKey(e => e.CustomerTypeId);
|
||||
|
||||
builder.Property(e => e.CustomerTypeId)
|
||||
.HasColumnName("CustomerTypeID")
|
||||
.HasMaxLength(10)
|
||||
.ValueGeneratedNever();
|
||||
builder.Property(e => e.CustomerTypeId)
|
||||
.HasColumnName("CustomerTypeID")
|
||||
.HasMaxLength(10)
|
||||
.ValueGeneratedNever();
|
||||
|
||||
builder.Property(e => e.CustomerDesc).HasColumnType("text");
|
||||
}
|
||||
}
|
||||
builder.Property(e => e.CustomerDesc).HasColumnType("text");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,44 +4,42 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|||
|
||||
namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping
|
||||
{
|
||||
public class CustomersMap : IEntityTypeConfiguration<Customer>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Customer> builder)
|
||||
{
|
||||
public class CustomersMap : IEntityTypeConfiguration<Customer>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Customer> builder)
|
||||
{
|
||||
builder.HasKey(e => e.CustomerId);
|
||||
|
||||
builder.HasKey(e => e.CustomerId);
|
||||
builder.HasIndex(e => e.City)
|
||||
.HasDatabaseName("City");
|
||||
|
||||
builder.HasIndex(e => e.City)
|
||||
.HasDatabaseName("City");
|
||||
builder.HasIndex(e => e.CompanyName)
|
||||
.HasDatabaseName("Customer_CompanyName");
|
||||
|
||||
builder.HasIndex(e => e.CompanyName)
|
||||
.HasDatabaseName("Customer_CompanyName");
|
||||
builder.HasIndex(e => e.PostalCode)
|
||||
.HasDatabaseName("Customer_Postal_ode");
|
||||
|
||||
builder.HasIndex(e => e.PostalCode)
|
||||
.HasDatabaseName("Customer_Postal_ode");
|
||||
builder.HasIndex(e => e.Region)
|
||||
.HasDatabaseName("Customer_Region");
|
||||
|
||||
builder.HasIndex(e => e.Region)
|
||||
.HasDatabaseName("Customer_Region");
|
||||
builder.Property(e => e.CustomerId)
|
||||
.HasColumnName("CustomerID")
|
||||
.HasMaxLength(5)
|
||||
.ValueGeneratedNever();
|
||||
|
||||
builder.Property(e => e.CustomerId)
|
||||
.HasColumnName("CustomerID")
|
||||
.HasMaxLength(5)
|
||||
.ValueGeneratedNever();
|
||||
builder.Property(e => e.Address).HasMaxLength(60);
|
||||
builder.Property(e => e.City).HasMaxLength(15);
|
||||
builder.Property(e => e.CompanyName)
|
||||
.IsRequired()
|
||||
.HasMaxLength(40);
|
||||
|
||||
builder.Property(e => e.Address).HasMaxLength(60);
|
||||
builder.Property(e => e.City).HasMaxLength(15);
|
||||
builder.Property(e => e.CompanyName)
|
||||
.IsRequired()
|
||||
.HasMaxLength(40);
|
||||
|
||||
builder.Property(e => e.ContactName).HasMaxLength(30);
|
||||
builder.Property(e => e.ContactTitle).HasMaxLength(30);
|
||||
builder.Property(e => e.Country).HasMaxLength(15);
|
||||
builder.Property(e => e.Fax).HasMaxLength(24);
|
||||
builder.Property(e => e.Phone).HasMaxLength(24);
|
||||
builder.Property(e => e.PostalCode).HasMaxLength(10);
|
||||
builder.Property(e => e.Region).HasMaxLength(15);
|
||||
|
||||
}
|
||||
}
|
||||
builder.Property(e => e.ContactName).HasMaxLength(30);
|
||||
builder.Property(e => e.ContactTitle).HasMaxLength(30);
|
||||
builder.Property(e => e.Country).HasMaxLength(15);
|
||||
builder.Property(e => e.Fax).HasMaxLength(24);
|
||||
builder.Property(e => e.Phone).HasMaxLength(24);
|
||||
builder.Property(e => e.PostalCode).HasMaxLength(10);
|
||||
builder.Property(e => e.Region).HasMaxLength(15);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,29 +4,29 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|||
|
||||
namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping
|
||||
{
|
||||
public class EmployeeTerritoriesMap : IEntityTypeConfiguration<EmployeeTerritory>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<EmployeeTerritory> builder)
|
||||
{
|
||||
builder.HasKey(e => new { e.EmployeeId, e.TerritoryId });
|
||||
public class EmployeeTerritoriesMap : IEntityTypeConfiguration<EmployeeTerritory>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<EmployeeTerritory> builder)
|
||||
{
|
||||
builder.HasKey(e => new { e.EmployeeId, e.TerritoryId });
|
||||
|
||||
builder.Property(e => e.EmployeeId).HasColumnName("EmployeeID");
|
||||
builder.Property(e => e.EmployeeId).HasColumnName("EmployeeID");
|
||||
|
||||
builder.Property(e => e.TerritoryId)
|
||||
.HasColumnName("TerritoryID")
|
||||
.HasMaxLength(20);
|
||||
builder.Property(e => e.TerritoryId)
|
||||
.HasColumnName("TerritoryID")
|
||||
.HasMaxLength(20);
|
||||
|
||||
builder.HasOne(d => d.Employee)
|
||||
.WithMany(p => p.EmployeeTerritories)
|
||||
.HasForeignKey(d => d.EmployeeId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_EmployeeTerritories_Employees");
|
||||
builder.HasOne(d => d.Employee)
|
||||
.WithMany(p => p.EmployeeTerritories)
|
||||
.HasForeignKey(d => d.EmployeeId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_EmployeeTerritories_Employees");
|
||||
|
||||
builder.HasOne(d => d.Territory)
|
||||
.WithMany(p => p.EmployeeTerritories)
|
||||
.HasForeignKey(d => d.TerritoryId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_EmployeeTerritories_Territories");
|
||||
}
|
||||
}
|
||||
builder.HasOne(d => d.Territory)
|
||||
.WithMany(p => p.EmployeeTerritories)
|
||||
.HasForeignKey(d => d.TerritoryId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_EmployeeTerritories_Territories");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping
|
|||
builder.Property(e => e.TitleOfCourtesy).HasMaxLength(25);
|
||||
|
||||
builder.HasOne(d => d.ReportsToNavigation)
|
||||
.WithMany(p => p!.InverseReportsToNavigation)
|
||||
.WithMany(p => p.InverseReportsToNavigation)
|
||||
.HasForeignKey(d => d.ReportsTo)
|
||||
.HasConstraintName("FK_Employees_Employees");
|
||||
}
|
||||
|
|
|
@ -4,39 +4,39 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|||
|
||||
namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping
|
||||
{
|
||||
public class OrderDetailsMap : IEntityTypeConfiguration<OrderDetail>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<OrderDetail> builder)
|
||||
{
|
||||
builder.HasKey(e => new { e.OrderId, e.ProductId });
|
||||
public class OrderDetailsMap : IEntityTypeConfiguration<OrderDetail>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<OrderDetail> builder)
|
||||
{
|
||||
builder.HasKey(e => new { e.OrderId, e.ProductId });
|
||||
|
||||
builder.ToTable("Order Details");
|
||||
builder.ToTable("Order Details");
|
||||
|
||||
builder.HasIndex(e => e.OrderId)
|
||||
.HasDatabaseName("OrdersOrder_Details");
|
||||
builder.HasIndex(e => e.OrderId)
|
||||
.HasDatabaseName("OrdersOrder_Details");
|
||||
|
||||
builder.HasIndex(e => e.ProductId)
|
||||
.HasDatabaseName("ProductsOrder_Details");
|
||||
builder.HasIndex(e => e.ProductId)
|
||||
.HasDatabaseName("ProductsOrder_Details");
|
||||
|
||||
builder.Property(e => e.OrderId).HasColumnName("OrderID");
|
||||
builder.Property(e => e.OrderId).HasColumnName("OrderID");
|
||||
|
||||
builder.Property(e => e.ProductId).HasColumnName("ProductID");
|
||||
builder.Property(e => e.ProductId).HasColumnName("ProductID");
|
||||
|
||||
builder.Property(e => e.Quantity).HasDefaultValue(1);
|
||||
builder.Property(e => e.Quantity).HasDefaultValue(1);
|
||||
|
||||
builder.Property(e => e.UnitPrice).HasColumnType("decimal(13, 4)");
|
||||
builder.Property(e => e.UnitPrice).HasColumnType("decimal(13, 4)");
|
||||
|
||||
builder.HasOne(d => d.Order)
|
||||
.WithMany(p => p.OrderDetails)
|
||||
.HasForeignKey(d => d.OrderId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_Order_Details_Orders");
|
||||
builder.HasOne(d => d.Order)
|
||||
.WithMany(p => p.OrderDetails)
|
||||
.HasForeignKey(d => d.OrderId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_Order_Details_Orders");
|
||||
|
||||
builder.HasOne(d => d.Product)
|
||||
.WithMany(p => p.OrderDetails)
|
||||
.HasForeignKey(d => d.ProductId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_Order_Details_Products");
|
||||
}
|
||||
}
|
||||
builder.HasOne(d => d.Product)
|
||||
.WithMany(p => p.OrderDetails)
|
||||
.HasForeignKey(d => d.ProductId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_Order_Details_Products");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,72 +8,71 @@ namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping
|
|||
{
|
||||
public void Configure(EntityTypeBuilder<Order> builder)
|
||||
{
|
||||
|
||||
builder.HasKey(e => e.OrderId);
|
||||
builder.HasKey(e => e.OrderId);
|
||||
|
||||
builder.HasIndex(e => e.CustomerId)
|
||||
.HasDatabaseName("Order_CustomersOrders");
|
||||
builder.HasIndex(e => e.CustomerId)
|
||||
.HasDatabaseName("Order_CustomersOrders");
|
||||
|
||||
builder.HasIndex(e => e.EmployeeId)
|
||||
.HasDatabaseName("Order_EmployeesOrders");
|
||||
builder.HasIndex(e => e.EmployeeId)
|
||||
.HasDatabaseName("Order_EmployeesOrders");
|
||||
|
||||
builder.HasIndex(e => e.OrderDate)
|
||||
.HasDatabaseName("Order_OrderDate");
|
||||
builder.HasIndex(e => e.OrderDate)
|
||||
.HasDatabaseName("Order_OrderDate");
|
||||
|
||||
builder.HasIndex(e => e.ShipPostalCode)
|
||||
.HasDatabaseName("Order_ShipPostalCode");
|
||||
builder.HasIndex(e => e.ShipPostalCode)
|
||||
.HasDatabaseName("Order_ShipPostalCode");
|
||||
|
||||
builder.HasIndex(e => e.ShipVia)
|
||||
.HasDatabaseName("Order_ShippersOrders");
|
||||
builder.HasIndex(e => e.ShipVia)
|
||||
.HasDatabaseName("Order_ShippersOrders");
|
||||
|
||||
builder.HasIndex(e => e.ShippedDate)
|
||||
.HasDatabaseName("Order_ShippedDate");
|
||||
builder.HasIndex(e => e.ShippedDate)
|
||||
.HasDatabaseName("Order_ShippedDate");
|
||||
|
||||
builder.Property(e => e.OrderId).HasColumnName("OrderID")
|
||||
.ValueGeneratedNever();
|
||||
builder.Property(e => e.OrderId).HasColumnName("OrderID")
|
||||
.ValueGeneratedNever();
|
||||
|
||||
builder.Property(e => e.CustomerId)
|
||||
.HasColumnName("CustomerID")
|
||||
.HasMaxLength(5);
|
||||
builder.Property(e => e.CustomerId)
|
||||
.HasColumnName("CustomerID")
|
||||
.HasMaxLength(5);
|
||||
|
||||
builder.Property(e => e.EmployeeId).HasColumnName("EmployeeID");
|
||||
builder.Property(e => e.EmployeeId).HasColumnName("EmployeeID");
|
||||
|
||||
builder.Property(e => e.Freight)
|
||||
.HasColumnType("decimal(13, 4)")
|
||||
.HasDefaultValue(0m);
|
||||
builder.Property(e => e.Freight)
|
||||
.HasColumnType("decimal(13, 4)")
|
||||
.HasDefaultValue(0m);
|
||||
|
||||
builder.Property(e => e.OrderDate).HasColumnType("datetime");
|
||||
builder.Property(e => e.OrderDate).HasColumnType("datetime");
|
||||
|
||||
builder.Property(e => e.RequiredDate).HasColumnType("datetime");
|
||||
builder.Property(e => e.RequiredDate).HasColumnType("datetime");
|
||||
|
||||
builder.Property(e => e.ShipAddress).HasMaxLength(60);
|
||||
builder.Property(e => e.ShipAddress).HasMaxLength(60);
|
||||
|
||||
builder.Property(e => e.ShipCity).HasMaxLength(15);
|
||||
builder.Property(e => e.ShipCity).HasMaxLength(15);
|
||||
|
||||
builder.Property(e => e.ShipCountry).HasMaxLength(15);
|
||||
builder.Property(e => e.ShipCountry).HasMaxLength(15);
|
||||
|
||||
builder.Property(e => e.ShipName).HasMaxLength(40);
|
||||
builder.Property(e => e.ShipName).HasMaxLength(40);
|
||||
|
||||
builder.Property(e => e.ShipPostalCode).HasMaxLength(10);
|
||||
builder.Property(e => e.ShipPostalCode).HasMaxLength(10);
|
||||
|
||||
builder.Property(e => e.ShipRegion).HasMaxLength(15);
|
||||
builder.Property(e => e.ShipRegion).HasMaxLength(15);
|
||||
|
||||
builder.Property(e => e.ShippedDate).HasColumnType("datetime");
|
||||
builder.Property(e => e.ShippedDate).HasColumnType("datetime");
|
||||
|
||||
builder.HasOne(d => d.Customer)
|
||||
.WithMany(p => p!.Orders)
|
||||
.HasForeignKey(d => d.CustomerId)
|
||||
.HasConstraintName("FK_Orders_Customers");
|
||||
builder.HasOne(d => d.Customer)
|
||||
.WithMany(p => p.Orders)
|
||||
.HasForeignKey(d => d.CustomerId)
|
||||
.HasConstraintName("FK_Orders_Customers");
|
||||
|
||||
builder.HasOne(d => d.Employee)
|
||||
.WithMany(p => p!.Orders)
|
||||
.HasForeignKey(d => d.EmployeeId)
|
||||
.HasConstraintName("FK_Orders_Employees");
|
||||
builder.HasOne(d => d.Employee)
|
||||
.WithMany(p => p.Orders)
|
||||
.HasForeignKey(d => d.EmployeeId)
|
||||
.HasConstraintName("FK_Orders_Employees");
|
||||
|
||||
builder.HasOne(d => d.ShipViaNavigation)
|
||||
.WithMany(p => p!.Orders)
|
||||
.HasForeignKey(d => d.ShipVia)
|
||||
.HasConstraintName("FK_Orders_Shippers");
|
||||
}
|
||||
builder.HasOne(d => d.ShipViaNavigation)
|
||||
.WithMany(p => p.Orders)
|
||||
.HasForeignKey(d => d.ShipVia)
|
||||
.HasConstraintName("FK_Orders_Shippers");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,12 +43,12 @@ namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping
|
|||
builder.Property(e => e.UnitsOnOrder).HasDefaultValue((short)0);
|
||||
|
||||
builder.HasOne(d => d.Category)
|
||||
.WithMany(p => p!.Products)
|
||||
.WithMany(p => p.Products)
|
||||
.HasForeignKey(d => d.CategoryId)
|
||||
.HasConstraintName("FK_Products_Categories");
|
||||
|
||||
builder.HasOne(d => d.Supplier)
|
||||
.WithMany(p => p!.Products)
|
||||
.WithMany(p => p.Products)
|
||||
.HasForeignKey(d => d.SupplierId)
|
||||
.HasConstraintName("FK_Products_Suppliers");
|
||||
}
|
||||
|
|
|
@ -4,19 +4,19 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|||
|
||||
namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind.Mapping
|
||||
{
|
||||
public class RegionMap : IEntityTypeConfiguration<Region>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Region> builder)
|
||||
{
|
||||
builder.HasKey(e => e.RegionId);
|
||||
public class RegionMap : IEntityTypeConfiguration<Region>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Region> builder)
|
||||
{
|
||||
builder.HasKey(e => e.RegionId);
|
||||
|
||||
builder.Property(e => e.RegionId)
|
||||
.HasColumnName("RegionID")
|
||||
.ValueGeneratedNever();
|
||||
builder.Property(e => e.RegionId)
|
||||
.HasColumnName("RegionID")
|
||||
.ValueGeneratedNever();
|
||||
|
||||
builder.Property(e => e.RegionDescription)
|
||||
.IsRequired()
|
||||
.HasMaxLength(50);
|
||||
}
|
||||
}
|
||||
builder.Property(e => e.RegionDescription)
|
||||
.IsRequired()
|
||||
.HasMaxLength(50);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ namespace LinqToDB.EntityFrameworkCore.SQLite.Tests.Models.Northwind
|
|||
|
||||
public NorthwindContext(DbContextOptions options) : base(options)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
|
|
|
@ -34,6 +34,5 @@ namespace LinqToDB.EntityFrameworkCore.SQLite.Tests
|
|||
ctx.Database.EnsureCreated();
|
||||
return ctx;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
public override ForMappingContextBase CreateContext()
|
||||
{
|
||||
var optionsBuilder = new DbContextOptionsBuilder<ForMappingContext>();
|
||||
optionsBuilder.UseSqlServer("Server=.;Database=ForMapping;Integrated Security=SSPI");
|
||||
optionsBuilder.UseSqlServer("Server=.;Database=ForMapping;Integrated Security=SSPI;Encrypt=true;TrustServerCertificate=true");
|
||||
optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory);
|
||||
|
||||
var options = optionsBuilder.Options;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Linq;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using LinqToDB.EntityFrameworkCore.BaseTests;
|
||||
using LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.IssueModel;
|
||||
|
@ -10,7 +11,7 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
[TestFixture]
|
||||
public class IssueTests : TestsBase
|
||||
{
|
||||
private DbContextOptions<IssueContext>? _options;
|
||||
private DbContextOptions<IssueContext> _options;
|
||||
private bool _created;
|
||||
|
||||
public IssueTests()
|
||||
|
@ -18,11 +19,12 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
InitOptions();
|
||||
}
|
||||
|
||||
[MemberNotNull(nameof(_options))]
|
||||
private void InitOptions()
|
||||
{
|
||||
var optionsBuilder = new DbContextOptionsBuilder<IssueContext>();
|
||||
|
||||
optionsBuilder.UseSqlServer("Server=.;Database=IssuesEFCore;Integrated Security=SSPI");
|
||||
optionsBuilder.UseSqlServer("Server=.;Database=IssuesEFCore;Integrated Security=SSPI;Encrypt=true;TrustServerCertificate=true");
|
||||
optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory);
|
||||
|
||||
_options = optionsBuilder.Options;
|
||||
|
@ -30,7 +32,7 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
|
||||
private IssueContext CreateContext()
|
||||
{
|
||||
var ctx = new IssueContext(_options!);
|
||||
var ctx = new IssueContext(_options);
|
||||
|
||||
if (!_created)
|
||||
{
|
||||
|
|
|
@ -9,7 +9,6 @@ using NUnit.Framework;
|
|||
|
||||
namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class JsonConverTests : TestsBase
|
||||
{
|
||||
|
@ -69,7 +68,7 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
entity.Property(e => e.NameLocalized)
|
||||
.HasColumnName("NameLocalized_JSON")
|
||||
.HasConversion(v => JsonConvert.SerializeObject(v),
|
||||
v => JsonConvert.DeserializeObject<LocalizedString>(v));
|
||||
v => JsonConvert.DeserializeObject<LocalizedString>(v) ?? new());
|
||||
entity.Property(e => e.CrashEnum).HasColumnType("tinyint");
|
||||
entity.Property(e => e.GuidColumn).HasColumnType("uniqueidentifier");
|
||||
});
|
||||
|
@ -85,13 +84,13 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
var optionsBuilder = new DbContextOptionsBuilder<JsonConvertContext>();
|
||||
//new SqlServerDbContextOptionsBuilder(optionsBuilder);
|
||||
|
||||
optionsBuilder.UseSqlServer("Server=.;Database=JsonConvertContext;Integrated Security=SSPI");
|
||||
optionsBuilder.UseSqlServer("Server=.;Database=JsonConvertContext;Integrated Security=SSPI;Encrypt=true;TrustServerCertificate=true");
|
||||
optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory);
|
||||
|
||||
_options = optionsBuilder.Options;
|
||||
}
|
||||
|
||||
public static string JsonValue(string column, [NotParameterized] string path)
|
||||
public static string JsonValue(string? column, [NotParameterized] string path)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
@ -133,7 +132,7 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
p.NameLocalized,
|
||||
p.CrashEnum,
|
||||
p.GuidColumn,
|
||||
JsonValue = JsonValue(p.JsonColumn!, path)
|
||||
JsonValue = JsonValue(p.JsonColumn, path)
|
||||
});
|
||||
|
||||
var item = items.FirstOrDefault();
|
||||
|
@ -152,7 +151,6 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
//
|
||||
// Assert.That(concrete.English, Is.EqualTo("English"));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,10 +5,8 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.ForMapping
|
|||
{
|
||||
public class ForMappingContext : ForMappingContextBase
|
||||
{
|
||||
|
||||
public ForMappingContext(DbContextOptions options) : base(options)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Inheritance
|
||||
{
|
||||
|
|
|
@ -8,10 +8,9 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.IssueModel
|
|||
|
||||
public int? ParentId { get; set; }
|
||||
|
||||
public Issue73Entity? Parent { get; set; } = null!;
|
||||
public Issue73Entity? Parent { get; set; }
|
||||
public List<Issue73Entity> Childs { get; set; } = null!;
|
||||
|
||||
public string Name { get; set; } = null!;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.IssueModel
|
|||
|
||||
public IssueContext(DbContextOptions options) : base(options)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
|
@ -20,9 +19,9 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.IssueModel
|
|||
b.HasKey(x => new { x.Id });
|
||||
|
||||
b.HasOne(x => x.Parent)
|
||||
.WithMany(x => x!.Childs)
|
||||
.WithMany(x => x.Childs)
|
||||
.HasForeignKey(x => new { x.ParentId })
|
||||
.HasPrincipalKey(x => new { x!.Id });
|
||||
.HasPrincipalKey(x => new { x.Id });
|
||||
|
||||
b.HasData(new[]
|
||||
{
|
||||
|
@ -43,7 +42,7 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.IssueModel
|
|||
modelBuilder
|
||||
.Entity<Patent>()
|
||||
.HasOne(p => p.Assessment)
|
||||
.WithOne(pa => pa!.Patent)
|
||||
.WithOne(pa => pa.Patent)
|
||||
.HasForeignKey<PatentAssessment>(pa => pa.PatentId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
|
|
|
@ -4,36 +4,34 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|||
|
||||
namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping
|
||||
{
|
||||
public class CustomerCustomerDemoMap : BaseEntityMap<CustomerCustomerDemo>
|
||||
{
|
||||
public override void Configure(EntityTypeBuilder<CustomerCustomerDemo> builder)
|
||||
{
|
||||
base.Configure(builder);
|
||||
public class CustomerCustomerDemoMap : BaseEntityMap<CustomerCustomerDemo>
|
||||
{
|
||||
public override void Configure(EntityTypeBuilder<CustomerCustomerDemo> builder)
|
||||
{
|
||||
base.Configure(builder);
|
||||
|
||||
|
||||
builder.HasKey(e => new { e.CustomerId, e.CustomerTypeId })
|
||||
.IsClustered(false);
|
||||
builder.HasKey(e => new { e.CustomerId, e.CustomerTypeId })
|
||||
.IsClustered(false);
|
||||
|
||||
builder.Property(e => e.CustomerId)
|
||||
.HasColumnName("CustomerID")
|
||||
.HasMaxLength(5);
|
||||
builder.Property(e => e.CustomerId)
|
||||
.HasColumnName("CustomerID")
|
||||
.HasMaxLength(5);
|
||||
|
||||
builder.Property(e => e.CustomerTypeId)
|
||||
.HasColumnName("CustomerTypeID")
|
||||
.HasMaxLength(10);
|
||||
builder.Property(e => e.CustomerTypeId)
|
||||
.HasColumnName("CustomerTypeID")
|
||||
.HasMaxLength(10);
|
||||
|
||||
builder.HasOne(d => d.Customer)
|
||||
.WithMany(p => p.CustomerCustomerDemo)
|
||||
.HasForeignKey(d => d.CustomerId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_CustomerCustomerDemo_Customers");
|
||||
builder.HasOne(d => d.Customer)
|
||||
.WithMany(p => p.CustomerCustomerDemo)
|
||||
.HasForeignKey(d => d.CustomerId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_CustomerCustomerDemo_Customers");
|
||||
|
||||
builder.HasOne(d => d.CustomerType)
|
||||
.WithMany(p => p.CustomerCustomerDemo)
|
||||
.HasForeignKey(d => d.CustomerTypeId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_CustomerCustomerDemo");
|
||||
|
||||
}
|
||||
}
|
||||
builder.HasOne(d => d.CustomerType)
|
||||
.WithMany(p => p.CustomerCustomerDemo)
|
||||
.HasForeignKey(d => d.CustomerTypeId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_CustomerCustomerDemo");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,21 +4,21 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|||
|
||||
namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping
|
||||
{
|
||||
public class CustomerDemographicsMap : BaseEntityMap<CustomerDemographics>
|
||||
{
|
||||
public override void Configure(EntityTypeBuilder<CustomerDemographics> builder)
|
||||
{
|
||||
base.Configure(builder);
|
||||
public class CustomerDemographicsMap : BaseEntityMap<CustomerDemographics>
|
||||
{
|
||||
public override void Configure(EntityTypeBuilder<CustomerDemographics> builder)
|
||||
{
|
||||
base.Configure(builder);
|
||||
|
||||
builder.HasKey(e => e.CustomerTypeId)
|
||||
.IsClustered(false);
|
||||
builder.HasKey(e => e.CustomerTypeId)
|
||||
.IsClustered(false);
|
||||
|
||||
builder.Property(e => e.CustomerTypeId)
|
||||
.HasColumnName("CustomerTypeID")
|
||||
.HasMaxLength(10)
|
||||
.ValueGeneratedNever();
|
||||
builder.Property(e => e.CustomerTypeId)
|
||||
.HasColumnName("CustomerTypeID")
|
||||
.HasMaxLength(10)
|
||||
.ValueGeneratedNever();
|
||||
|
||||
builder.Property(e => e.CustomerDesc).HasColumnType("ntext");
|
||||
}
|
||||
}
|
||||
builder.Property(e => e.CustomerDesc).HasColumnType("ntext");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,45 +4,44 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|||
|
||||
namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping
|
||||
{
|
||||
public class CustomersMap : BaseEntityMap<Customer>
|
||||
{
|
||||
public override void Configure(EntityTypeBuilder<Customer> builder)
|
||||
{
|
||||
base.Configure(builder);
|
||||
public class CustomersMap : BaseEntityMap<Customer>
|
||||
{
|
||||
public override void Configure(EntityTypeBuilder<Customer> builder)
|
||||
{
|
||||
base.Configure(builder);
|
||||
|
||||
builder.HasKey(e => e.CustomerId);
|
||||
builder.HasKey(e => e.CustomerId);
|
||||
|
||||
builder.HasIndex(e => e.City)
|
||||
.HasDatabaseName("City");
|
||||
builder.HasIndex(e => e.City)
|
||||
.HasDatabaseName("City");
|
||||
|
||||
builder.HasIndex(e => e.CompanyName)
|
||||
.HasDatabaseName("CompanyName");
|
||||
builder.HasIndex(e => e.CompanyName)
|
||||
.HasDatabaseName("CompanyName");
|
||||
|
||||
builder.HasIndex(e => e.PostalCode)
|
||||
.HasDatabaseName("PostalCode");
|
||||
builder.HasIndex(e => e.PostalCode)
|
||||
.HasDatabaseName("PostalCode");
|
||||
|
||||
builder.HasIndex(e => e.Region)
|
||||
.HasDatabaseName("Region");
|
||||
builder.HasIndex(e => e.Region)
|
||||
.HasDatabaseName("Region");
|
||||
|
||||
builder.Property(e => e.CustomerId)
|
||||
.HasColumnName("CustomerID")
|
||||
.HasMaxLength(5)
|
||||
.ValueGeneratedNever();
|
||||
builder.Property(e => e.CustomerId)
|
||||
.HasColumnName("CustomerID")
|
||||
.HasMaxLength(5)
|
||||
.ValueGeneratedNever();
|
||||
|
||||
builder.Property(e => e.Address).HasMaxLength(60);
|
||||
builder.Property(e => e.City).HasMaxLength(15);
|
||||
builder.Property(e => e.CompanyName)
|
||||
.IsRequired()
|
||||
.HasMaxLength(40);
|
||||
builder.Property(e => e.Address).HasMaxLength(60);
|
||||
builder.Property(e => e.City).HasMaxLength(15);
|
||||
builder.Property(e => e.CompanyName)
|
||||
.IsRequired()
|
||||
.HasMaxLength(40);
|
||||
|
||||
builder.Property(e => e.ContactName).HasMaxLength(30);
|
||||
builder.Property(e => e.ContactTitle).HasMaxLength(30);
|
||||
builder.Property(e => e.Country).HasMaxLength(15);
|
||||
builder.Property(e => e.Fax).HasMaxLength(24);
|
||||
builder.Property(e => e.Phone).HasMaxLength(24);
|
||||
builder.Property(e => e.PostalCode).HasMaxLength(10);
|
||||
builder.Property(e => e.Region).HasMaxLength(15);
|
||||
|
||||
}
|
||||
}
|
||||
builder.Property(e => e.ContactName).HasMaxLength(30);
|
||||
builder.Property(e => e.ContactTitle).HasMaxLength(30);
|
||||
builder.Property(e => e.Country).HasMaxLength(15);
|
||||
builder.Property(e => e.Fax).HasMaxLength(24);
|
||||
builder.Property(e => e.Phone).HasMaxLength(24);
|
||||
builder.Property(e => e.PostalCode).HasMaxLength(10);
|
||||
builder.Property(e => e.Region).HasMaxLength(15);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,32 +4,32 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|||
|
||||
namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping
|
||||
{
|
||||
public class EmployeeTerritoriesMap : BaseEntityMap<EmployeeTerritory>
|
||||
{
|
||||
public override void Configure(EntityTypeBuilder<EmployeeTerritory> builder)
|
||||
{
|
||||
base.Configure(builder);
|
||||
public class EmployeeTerritoriesMap : BaseEntityMap<EmployeeTerritory>
|
||||
{
|
||||
public override void Configure(EntityTypeBuilder<EmployeeTerritory> builder)
|
||||
{
|
||||
base.Configure(builder);
|
||||
|
||||
builder.HasKey(e => new { e.EmployeeId, e.TerritoryId })
|
||||
.IsClustered(false);
|
||||
builder.HasKey(e => new { e.EmployeeId, e.TerritoryId })
|
||||
.IsClustered(false);
|
||||
|
||||
builder.Property(e => e.EmployeeId).HasColumnName("EmployeeID");
|
||||
builder.Property(e => e.EmployeeId).HasColumnName("EmployeeID");
|
||||
|
||||
builder.Property(e => e.TerritoryId)
|
||||
.HasColumnName("TerritoryID")
|
||||
.HasMaxLength(20);
|
||||
builder.Property(e => e.TerritoryId)
|
||||
.HasColumnName("TerritoryID")
|
||||
.HasMaxLength(20);
|
||||
|
||||
builder.HasOne(d => d.Employee)
|
||||
.WithMany(p => p.EmployeeTerritories)
|
||||
.HasForeignKey(d => d.EmployeeId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_EmployeeTerritories_Employees");
|
||||
builder.HasOne(d => d.Employee)
|
||||
.WithMany(p => p.EmployeeTerritories)
|
||||
.HasForeignKey(d => d.EmployeeId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_EmployeeTerritories_Employees");
|
||||
|
||||
builder.HasOne(d => d.Territory)
|
||||
.WithMany(p => p.EmployeeTerritories)
|
||||
.HasForeignKey(d => d.TerritoryId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_EmployeeTerritories_Territories");
|
||||
}
|
||||
}
|
||||
builder.HasOne(d => d.Territory)
|
||||
.WithMany(p => p.EmployeeTerritories)
|
||||
.HasForeignKey(d => d.TerritoryId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_EmployeeTerritories_Territories");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping
|
|||
builder.Property(e => e.TitleOfCourtesy).HasMaxLength(25);
|
||||
|
||||
builder.HasOne(d => d.ReportsToNavigation)
|
||||
.WithMany(p => p!.InverseReportsToNavigation)
|
||||
.WithMany(p => p.InverseReportsToNavigation)
|
||||
.HasForeignKey(d => d.ReportsTo)
|
||||
.HasConstraintName("FK_Employees_Employees");
|
||||
}
|
||||
|
|
|
@ -63,17 +63,17 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping
|
|||
builder.Property(e => e.ShippedDate).HasColumnType("datetime");
|
||||
|
||||
builder.HasOne(d => d.Customer)
|
||||
.WithMany(p => p!.Orders)
|
||||
.WithMany(p => p.Orders)
|
||||
.HasForeignKey(d => d.CustomerId)
|
||||
.HasConstraintName("FK_Orders_Customers");
|
||||
|
||||
builder.HasOne(d => d.Employee)
|
||||
.WithMany(p => p!.Orders)
|
||||
.WithMany(p => p.Orders)
|
||||
.HasForeignKey(d => d.EmployeeId)
|
||||
.HasConstraintName("FK_Orders_Employees");
|
||||
|
||||
builder.HasOne(d => d.ShipViaNavigation)
|
||||
.WithMany(p => p!.Orders)
|
||||
.WithMany(p => p.Orders)
|
||||
.HasForeignKey(d => d.ShipVia)
|
||||
.HasConstraintName("FK_Orders_Shippers");
|
||||
}
|
||||
|
|
|
@ -43,12 +43,12 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping
|
|||
builder.Property(e => e.UnitsOnOrder).HasDefaultValueSql("((0))");
|
||||
|
||||
builder.HasOne(d => d.Category)
|
||||
.WithMany(p => p!.Products)
|
||||
.WithMany(p => p.Products)
|
||||
.HasForeignKey(d => d.CategoryId)
|
||||
.HasConstraintName("FK_Products_Categories");
|
||||
|
||||
builder.HasOne(d => d.Supplier)
|
||||
.WithMany(p => p!.Products)
|
||||
.WithMany(p => p.Products)
|
||||
.HasForeignKey(d => d.SupplierId)
|
||||
.HasConstraintName("FK_Products_Suppliers");
|
||||
}
|
||||
|
|
|
@ -4,22 +4,22 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|||
|
||||
namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping
|
||||
{
|
||||
public class RegionMap : BaseEntityMap<Region>
|
||||
{
|
||||
public override void Configure(EntityTypeBuilder<Region> builder)
|
||||
{
|
||||
base.Configure(builder);
|
||||
public class RegionMap : BaseEntityMap<Region>
|
||||
{
|
||||
public override void Configure(EntityTypeBuilder<Region> builder)
|
||||
{
|
||||
base.Configure(builder);
|
||||
|
||||
builder.HasKey(e => e.RegionId)
|
||||
.IsClustered(false);
|
||||
builder.HasKey(e => e.RegionId)
|
||||
.IsClustered(false);
|
||||
|
||||
builder.Property(e => e.RegionId)
|
||||
.HasColumnName("RegionID")
|
||||
.ValueGeneratedNever();
|
||||
builder.Property(e => e.RegionId)
|
||||
.HasColumnName("RegionID")
|
||||
.ValueGeneratedNever();
|
||||
|
||||
builder.Property(e => e.RegionDescription)
|
||||
.IsRequired()
|
||||
.HasMaxLength(50);
|
||||
}
|
||||
}
|
||||
builder.Property(e => e.RegionDescription)
|
||||
.IsRequired()
|
||||
.HasMaxLength(50);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,31 +4,31 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|||
|
||||
namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping
|
||||
{
|
||||
public class TerritoriesMap : BaseEntityMap<Territory>
|
||||
{
|
||||
public override void Configure(EntityTypeBuilder<Territory> builder)
|
||||
{
|
||||
base.Configure(builder);
|
||||
public class TerritoriesMap : BaseEntityMap<Territory>
|
||||
{
|
||||
public override void Configure(EntityTypeBuilder<Territory> builder)
|
||||
{
|
||||
base.Configure(builder);
|
||||
|
||||
builder.HasKey(e => e.TerritoryId)
|
||||
.IsClustered(false);
|
||||
builder.HasKey(e => e.TerritoryId)
|
||||
.IsClustered(false);
|
||||
|
||||
builder.Property(e => e.TerritoryId)
|
||||
.HasColumnName("TerritoryID")
|
||||
.HasMaxLength(20)
|
||||
.ValueGeneratedNever();
|
||||
builder.Property(e => e.TerritoryId)
|
||||
.HasColumnName("TerritoryID")
|
||||
.HasMaxLength(20)
|
||||
.ValueGeneratedNever();
|
||||
|
||||
builder.Property(e => e.RegionId).HasColumnName("RegionID");
|
||||
builder.Property(e => e.RegionId).HasColumnName("RegionID");
|
||||
|
||||
builder.Property(e => e.TerritoryDescription)
|
||||
.IsRequired()
|
||||
.HasMaxLength(50);
|
||||
builder.Property(e => e.TerritoryDescription)
|
||||
.IsRequired()
|
||||
.HasMaxLength(50);
|
||||
|
||||
builder.HasOne(d => d.Region)
|
||||
.WithMany(p => p.Territories)
|
||||
.HasForeignKey(d => d.RegionId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_Territories_Region");
|
||||
}
|
||||
}
|
||||
builder.HasOne(d => d.Region)
|
||||
.WithMany(p => p.Territories)
|
||||
.HasForeignKey(d => d.RegionId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_Territories_Region");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind
|
|||
|
||||
public NorthwindContext(DbContextOptions options) : base(options)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[DbFunction("ProcessLong", "dbo")]
|
||||
|
@ -73,7 +72,7 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind
|
|||
MemberHelper.MethodOf(() => ((NorthwindContext)null!).ConfigureEntityFilter<BaseEntity>(null!)).GetGenericMethodDefinition();
|
||||
|
||||
public void ConfigureEntityFilter<TEntity>(ModelBuilder builder)
|
||||
where TEntity: class, ISoftDelete
|
||||
where TEntity: class, ISoftDelete
|
||||
{
|
||||
NorthwindContext? obj = null;
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading;
|
||||
|
@ -10,6 +11,58 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
{
|
||||
public static class QueryableExtensions
|
||||
{
|
||||
public static IQueryable<T> AnyFromItems<T, TItem>(this IQueryable<T> source, IEnumerable<TItem> items,
|
||||
string propName)
|
||||
{
|
||||
var entityParam = Expression.Parameter(typeof(T), "e");
|
||||
var itemParam = Expression.Parameter(typeof(TItem), "i");
|
||||
|
||||
var anyPredicate =
|
||||
Expression.Lambda(
|
||||
Expression.Equal(itemParam, Expression.PropertyOrField(entityParam, propName)),
|
||||
itemParam);
|
||||
|
||||
var filterLambda =
|
||||
Expression.Lambda<Func<T, bool>>(
|
||||
Expression.Call(typeof(Enumerable), nameof(Enumerable.Any), new[] { typeof(TItem) },
|
||||
Expression.Constant(items), anyPredicate),
|
||||
entityParam);
|
||||
|
||||
return source.Where(filterLambda);
|
||||
}
|
||||
|
||||
public static IQueryable<T> AnyFromItems<T>(this IQueryable<T> source, string items, string propName)
|
||||
{
|
||||
var strItems = items.Split(",", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
|
||||
var entityParam = Expression.Parameter(typeof(T), "e");
|
||||
var propExpression = Expression.PropertyOrField(entityParam, propName);
|
||||
var itemType = propExpression.Type;
|
||||
var itemParam = Expression.Parameter(itemType, "i");
|
||||
|
||||
var anyPredicate =
|
||||
Expression.Lambda(
|
||||
Expression.Equal(itemParam, Expression.PropertyOrField(entityParam, propName)),
|
||||
itemParam);
|
||||
|
||||
// apply conversion
|
||||
var itemsExpression = Expression.Call(typeof(QueryableExtensions), nameof(QueryableExtensions.ParseItems),
|
||||
new[] { itemType }, Expression.Constant(strItems));
|
||||
|
||||
var filterLambda =
|
||||
Expression.Lambda<Func<T, bool>>(
|
||||
Expression.Call(typeof(Enumerable), nameof(Enumerable.Any), new[] { itemType },
|
||||
itemsExpression, anyPredicate),
|
||||
entityParam);
|
||||
|
||||
return source.Where(filterLambda);
|
||||
}
|
||||
|
||||
private static IEnumerable<TItem> ParseItems<TItem>(IEnumerable<string> items)
|
||||
{
|
||||
return items.Select(i => (TItem)Convert.ChangeType(i, typeof(TItem)));
|
||||
}
|
||||
|
||||
public static async Task<IEnumerable<T>> FilterExistentAsync<T, TProp>(this ICollection<T> items,
|
||||
IQueryable<T> dbQuery, Expression<Func<T, TProp>> prop, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
@ -70,7 +123,7 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
return query.Where(MakePropertiesPredicate<T, TValue>(pattern, searchValue, isOr));
|
||||
}
|
||||
|
||||
class ExpressionReplacer : ExpressionVisitor
|
||||
sealed class ExpressionReplacer : ExpressionVisitor
|
||||
{
|
||||
readonly IDictionary<Expression, Expression> _replaceMap;
|
||||
|
||||
|
@ -79,7 +132,10 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
_replaceMap = replaceMap ?? throw new ArgumentNullException(nameof(replaceMap));
|
||||
}
|
||||
|
||||
public override Expression Visit(Expression node)
|
||||
// TODO: uncomment after azure pipelines updated to 17.4
|
||||
//[return: NotNullIfNotNull(nameof(node))]
|
||||
[return: NotNullIfNotNull("node")]
|
||||
public override Expression? Visit(Expression? node)
|
||||
{
|
||||
if (node != null && _replaceMap.TryGetValue(node, out var replacement))
|
||||
return replacement;
|
||||
|
|
|
@ -5,7 +5,6 @@ using FluentAssertions;
|
|||
using LinqToDB.Data;
|
||||
using LinqToDB.EntityFrameworkCore.BaseTests;
|
||||
using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind;
|
||||
using LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Inheritance;
|
||||
using LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind;
|
||||
using LinqToDB.Expressions;
|
||||
using LinqToDB.Mapping;
|
||||
|
@ -17,8 +16,7 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
[TestFixture]
|
||||
public class ToolsTests : TestsBase
|
||||
{
|
||||
private readonly DbContextOptions _northwindOptions;
|
||||
private DbContextOptions? _inheritanceOptions;
|
||||
private readonly DbContextOptions _options;
|
||||
private readonly DbContextOptions<NorthwindContext> _inmemoryOptions;
|
||||
|
||||
static ToolsTests()
|
||||
|
@ -27,37 +25,19 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
DataConnection.TurnTraceSwitchOn();
|
||||
}
|
||||
|
||||
static DbContextOptions CreateNorthwindOptions()
|
||||
{
|
||||
var optionsBuilder = new DbContextOptionsBuilder<NorthwindContext>();
|
||||
//new SqlServerDbContextOptionsBuilder(optionsBuilder);
|
||||
|
||||
optionsBuilder.UseSqlServer("Server=.;Database=NorthwindEFCore;Integrated Security=SSPI");
|
||||
optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory);
|
||||
|
||||
return optionsBuilder.Options;
|
||||
}
|
||||
|
||||
static DbContextOptions CreateInheritanceOptions()
|
||||
{
|
||||
var optionsBuilder = new DbContextOptionsBuilder<InheritanceContext>();
|
||||
//new SqlServerDbContextOptionsBuilder(optionsBuilder);
|
||||
|
||||
optionsBuilder.UseSqlServer("Server=.;Database=InheritanceEFCore;Integrated Security=SSPI");
|
||||
optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory);
|
||||
optionsBuilder.EnableSensitiveDataLogging();
|
||||
|
||||
return optionsBuilder.Options;
|
||||
}
|
||||
|
||||
public ToolsTests()
|
||||
{
|
||||
_northwindOptions = CreateNorthwindOptions();
|
||||
|
||||
|
||||
var optionsBuilder = new DbContextOptionsBuilder<NorthwindContext>();
|
||||
//new SqlServerDbContextOptionsBuilder(optionsBuilder);
|
||||
|
||||
optionsBuilder.UseSqlServer("Server=.;Database=NorthwindEFCore;Integrated Security=SSPI;Encrypt=true;TrustServerCertificate=true");
|
||||
optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory);
|
||||
|
||||
_options = optionsBuilder.Options;
|
||||
|
||||
optionsBuilder = new DbContextOptionsBuilder<NorthwindContext>();
|
||||
//new SqlServerDbContextOptionsBuilder(optionsBuilder);
|
||||
|
||||
optionsBuilder.UseInMemoryDatabase("sample");
|
||||
optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory);
|
||||
|
||||
|
@ -86,7 +66,7 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
|
||||
private NorthwindContext CreateContext(bool enableFilter)
|
||||
{
|
||||
var ctx = new NorthwindContext(_northwindOptions);
|
||||
var ctx = new NorthwindContext(_options);
|
||||
ctx.IsSoftDeleteFilterEnabled = enableFilter;
|
||||
//ctx.Database.EnsureDeleted();
|
||||
if (ctx.Database.EnsureCreated())
|
||||
|
@ -96,23 +76,6 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
return ctx;
|
||||
}
|
||||
|
||||
private InheritanceContext CreateInheritanceContext()
|
||||
{
|
||||
var recreate = _inheritanceOptions == null;
|
||||
|
||||
if (_inheritanceOptions == null)
|
||||
_inheritanceOptions = CreateInheritanceOptions();
|
||||
|
||||
var ctx = new InheritanceContext(_inheritanceOptions);
|
||||
if (recreate)
|
||||
{
|
||||
ctx.Database.EnsureDeleted();
|
||||
ctx.Database.EnsureCreated();
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
public class VwProductAndDescription
|
||||
{
|
||||
public int ProductId { get; set; }
|
||||
|
@ -207,7 +170,7 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
[Test]
|
||||
public void TestCreateFromOptions()
|
||||
{
|
||||
using (var db = _northwindOptions.CreateLinqToDbConnection())
|
||||
using (var db = _options.CreateLinqToDbConnection())
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -226,19 +189,19 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
// Date = Model.TestFunctions.GetDate(),
|
||||
// Len = Model.TestFunctions.Len(p.Name),
|
||||
DiffYear1 = EF.Functions.DateDiffYear(p.ShippedDate, p.OrderDate),
|
||||
DiffYear2 = p.OrderDate == null ? (int?)null : EF.Functions.DateDiffYear(p.ShippedDate, p.OrderDate.Value),
|
||||
DiffYear2 = p.OrderDate == null ? null : EF.Functions.DateDiffYear(p.ShippedDate, p.OrderDate.Value),
|
||||
DiffMonth1 = EF.Functions.DateDiffMonth(p.ShippedDate, p.OrderDate),
|
||||
DiffMonth2 = p.OrderDate == null ? (int?)null : EF.Functions.DateDiffMonth(p.ShippedDate, p.OrderDate.Value),
|
||||
DiffMonth2 = p.OrderDate == null ? null : EF.Functions.DateDiffMonth(p.ShippedDate, p.OrderDate.Value),
|
||||
DiffDay1 = EF.Functions.DateDiffDay(p.ShippedDate, p.OrderDate),
|
||||
DiffDay2 = p.OrderDate == null ? (int?)null : EF.Functions.DateDiffDay(p.ShippedDate, p.OrderDate.Value),
|
||||
DiffDay2 = p.OrderDate == null ? null : EF.Functions.DateDiffDay(p.ShippedDate, p.OrderDate.Value),
|
||||
DiffHour1 = EF.Functions.DateDiffHour(p.ShippedDate, p.OrderDate),
|
||||
DiffHour2 = p.OrderDate == null ? (int?)null : EF.Functions.DateDiffHour(p.ShippedDate, p.OrderDate.Value),
|
||||
DiffHour2 = p.OrderDate == null ? null : EF.Functions.DateDiffHour(p.ShippedDate, p.OrderDate.Value),
|
||||
DiffMinute1 = EF.Functions.DateDiffMinute(p.ShippedDate, p.OrderDate),
|
||||
DiffMinute2 = p.OrderDate == null ? (int?)null : EF.Functions.DateDiffMinute(p.ShippedDate, p.OrderDate.Value),
|
||||
DiffMinute2 = p.OrderDate == null ? null : EF.Functions.DateDiffMinute(p.ShippedDate, p.OrderDate.Value),
|
||||
DiffSecond1 = EF.Functions.DateDiffSecond(p.ShippedDate, p.OrderDate),
|
||||
DiffSecond2 = p.OrderDate == null ? (int?)null : EF.Functions.DateDiffSecond(p.ShippedDate, p.OrderDate.Value),
|
||||
DiffSecond2 = p.OrderDate == null ? null : EF.Functions.DateDiffSecond(p.ShippedDate, p.OrderDate.Value),
|
||||
DiffMillisecond1 = EF.Functions.DateDiffMillisecond(p.ShippedDate, p.ShippedDate!.Value.AddMilliseconds(100)),
|
||||
DiffMillisecond2 = p.OrderDate == null ? (int?)null : EF.Functions.DateDiffMillisecond(p.ShippedDate, p.ShippedDate.Value.AddMilliseconds(100)),
|
||||
DiffMillisecond2 = p.OrderDate == null ? null : EF.Functions.DateDiffMillisecond(p.ShippedDate, p.ShippedDate.Value.AddMilliseconds(100)),
|
||||
};
|
||||
|
||||
// var items1 = query.ToArray();
|
||||
|
@ -571,7 +534,7 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
orderDetail.UnitPrice = orderDetail.UnitPrice * 1.1m;
|
||||
|
||||
ctx.ChangeTracker.DetectChanges();
|
||||
var changedEntry = ctx.ChangeTracker.Entries().Where(e => e.State == EntityState.Modified).Single();
|
||||
var changedEntry = ctx.ChangeTracker.Entries().Single(e => e.State == EntityState.Modified);
|
||||
ctx.SaveChanges();
|
||||
}
|
||||
}
|
||||
|
@ -594,7 +557,7 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
orderDetail.UnitPrice = orderDetail.UnitPrice * 1.1m;
|
||||
|
||||
ctx.ChangeTracker.DetectChanges();
|
||||
var changedEntry = ctx.ChangeTracker.Entries().Where(e => e.State == EntityState.Modified).SingleOrDefault();
|
||||
var changedEntry = ctx.ChangeTracker.Entries().SingleOrDefault(e => e.State == EntityState.Modified);
|
||||
Assert.AreEqual(changedEntry, null);
|
||||
ctx.SaveChanges();
|
||||
}
|
||||
|
@ -620,7 +583,7 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
orderDetail.UnitPrice = orderDetail.UnitPrice * 1.1m;
|
||||
|
||||
ctx.ChangeTracker.DetectChanges();
|
||||
var changedEntry = ctx.ChangeTracker.Entries().Where(e => e.State == EntityState.Modified).SingleOrDefault();
|
||||
var changedEntry = ctx.ChangeTracker.Entries().SingleOrDefault(e => e.State == EntityState.Modified);
|
||||
Assert.AreEqual(changedEntry, null);
|
||||
ctx.SaveChanges();
|
||||
}
|
||||
|
@ -631,23 +594,6 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestChangeTrackerTemporaryTable([Values(true, false)] bool enableFilter)
|
||||
{
|
||||
using var ctx = CreateContext(enableFilter);
|
||||
|
||||
var query = ctx.Orders;
|
||||
|
||||
using var db = ctx.CreateLinqToDbConnection();
|
||||
|
||||
using var temp = await db.CreateTempTableAsync(query, tableName: "#Orders");
|
||||
|
||||
var result = temp.Take(2).ToList();
|
||||
|
||||
ctx.Orders.Local.Should().BeEmpty();
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void NavigationProperties()
|
||||
{
|
||||
|
@ -890,46 +836,6 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
|
|||
str.Should().Contain("Tagged query");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestInheritanceBulkCopy([Values] BulkCopyType copyType)
|
||||
{
|
||||
using (var ctx = CreateInheritanceContext())
|
||||
{
|
||||
var data = new BlogBase[] { new Blog() { Url = "BlogUrl" }, new RssBlog() { Url = "RssUrl" } };
|
||||
|
||||
ctx.BulkCopy(new BulkCopyOptions(){ BulkCopyType = BulkCopyType.RowByRow }, data);
|
||||
|
||||
var items = ctx.Blogs.ToArray();
|
||||
|
||||
items[0].Should().BeOfType<Blog>();
|
||||
((Blog)items[0]).Url.Should().Be("BlogUrl");
|
||||
|
||||
items[1].Should().BeOfType<RssBlog>();
|
||||
((RssBlog)items[1]).Url.Should().Be("RssUrl");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
[Test]
|
||||
public void TestInheritanceShadowBulkCopy([Values] BulkCopyType copyType)
|
||||
{
|
||||
using (var ctx = CreateInheritanceContext())
|
||||
{
|
||||
var data = new ShadowBlogBase[] { new ShadowBlog() { Url = "BlogUrl" }, new ShadowRssBlog() { Url = "RssUrl" } };
|
||||
|
||||
ctx.BulkCopy(new BulkCopyOptions(){ BulkCopyType = BulkCopyType.RowByRow }, data);
|
||||
|
||||
var items = ctx.ShadowBlogs.ToArray();
|
||||
|
||||
items[0].Should().BeOfType<ShadowBlog>();
|
||||
((ShadowBlog)items[0]).Url.Should().Be("BlogUrl");
|
||||
|
||||
items[1].Should().BeOfType<ShadowRssBlog>();
|
||||
((ShadowRssBlog)items[1]).Url.Should().Be("RssUrl");
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.ValueConversion
|
|||
|
||||
optionsBuilder
|
||||
.ReplaceService<IValueConverterSelector, IdValueConverterSelector>()
|
||||
.UseSqlServer("Server=.;Database=ConverterTests;Integrated Security=SSPI")
|
||||
.UseSqlServer("Server=.;Database=ConverterTests;Integrated Security=SSPI;Encrypt=true;TrustServerCertificate=true")
|
||||
.UseLoggerFactory(TestUtils.LoggerFactory);;
|
||||
|
||||
_options = optionsBuilder.Options;
|
||||
|
@ -58,7 +58,7 @@ namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.ValueConversion
|
|||
var ef = ctx.Subdivisions.Where(s => s.Id == 1L).ToArray();
|
||||
var ltdb = ctx.Subdivisions.ToLinqToDB().Where(s => s.Id == 1L).ToArray();
|
||||
|
||||
var id = new Nullable<Id<SubDivision, long>>(0L.AsId<SubDivision>());
|
||||
var id = new Id<SubDivision, long>?(0L.AsId<SubDivision>());
|
||||
var ltdb2 = ctx.Subdivisions.ToLinqToDB().Where(s => s.Id == id).ToArray();
|
||||
|
||||
var ids = new[] {1L.AsId<SubDivision>(), 2L.AsId<SubDivision>(),};
|
||||
|
|
|
@ -4,5 +4,4 @@
|
|||
{
|
||||
public TKey Id { get; }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
variables:
|
||||
solution: 'linq2db.EFCore.sln'
|
||||
build_configuration: 'Release'
|
||||
assemblyVersion: 5.13.0
|
||||
nugetVersion: 5.13.0
|
||||
assemblyVersion: 7.0.0
|
||||
nugetVersion: 7.0.0
|
||||
artifact_nugets: 'nugets'
|
||||
|
||||
# build on commits to important branches (master + release branches):
|
||||
|
@ -32,6 +32,12 @@ stages:
|
|||
|
||||
steps:
|
||||
|
||||
|
||||
- task: UseDotNet@2
|
||||
displayName: 'Install .NET 7'
|
||||
inputs:
|
||||
version: 7.x
|
||||
|
||||
- task: PowerShell@2
|
||||
inputs:
|
||||
filePath: '$(Build.SourcesDirectory)/Build/SetVersion.ps1'
|
||||
|
|
|
@ -11,7 +11,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{A3F30061
|
|||
.gitignore = .gitignore
|
||||
azure-pipelines.yml = azure-pipelines.yml
|
||||
Directory.Packages.props = Directory.Packages.props
|
||||
global.json = global.json
|
||||
Build\linq2db.Default.props = Build\linq2db.Default.props
|
||||
Build\linq2db.snk = Build\linq2db.snk
|
||||
Build\linq2db.Tests.props = Build\linq2db.Tests.props
|
||||
|
@ -41,7 +40,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LinqToDB.EntityFrameworkCor
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LinqToDB.EntityFrameworkCore.SQLite.Tests", "Tests\LinqToDB.EntityFrameworkCore.SQLite.Tests\LinqToDB.EntityFrameworkCore.SQLite.Tests.csproj", "{615C5697-5FA7-490C-8812-3D61994A8AC1}"
|
||||
EndProject
|
||||
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "LinqToDB.EntityFrameworkCore.FSharpTests", "Tests\LinqToDB.EntityFrameworkCore.FSharpTests\LinqToDB.EntityFrameworkCore.FSharpTests.fsproj", "{ECF4637B-1C93-4D87-BDF2-E7F4DF7ED5C9}"
|
||||
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "LinqToDB.EntityFrameworkCore.FSharpTests", "Tests\LinqToDB.EntityFrameworkCore.FSharpTests\LinqToDB.EntityFrameworkCore.FSharpTests.fsproj", "{ECF4637B-1C93-4D87-BDF2-E7F4DF7ED5C9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
|
Загрузка…
Ссылка в новой задаче