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

Commit 06ba6b9

Browse files
authored
Cleanup tasks (EF3) (#81)
* - add missing xml docs - enable C#9 and NRT - fix warnings (cherry picked from commit 33911fb) # Conflicts: # Build/linq2db.Tests.props # Source/LinqToDB.EntityFrameworkCore/EFCoreMetadataReader.cs # Source/LinqToDB.EntityFrameworkCore/ILinqToDBForEFTools.cs # Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFTools.cs # Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFToolsImplDefault.cs # Source/LinqToDB.EntityFrameworkCore/linq2db.EntityFrameworkCore.csproj # Tests/LinqToDB.EntityFrameworkCore.BaseTests/Models/Northwind/NorthwindData.cs * post-merge fixes
1 parent 3688e3b commit 06ba6b9

File tree

79 files changed

+1889
-2482
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+1889
-2482
lines changed

Build/linq2db.Default.props

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,18 @@
22
<PropertyGroup>
33
<Version>3.8.0</Version>
44

5-
<Description>Allows to execute Linq to DB (linq2db) queries in Entity Framework Core DbContext.</Description>
6-
<Title>Linq to DB (linq2db) extensions for Entity Framework Core</Title>
7-
<AssemblyTitle>$(Title)</AssemblyTitle>
85
<Authors>Svyatoslav Danyliv, Igor Tkachev, Dmitry Lukashenko, Ilya Chudin</Authors>
96
<Product>Linq to DB</Product>
107
<Company>linq2db.net</Company>
118
<Copyright>2002-2020 linq2db.net</Copyright>
129
<RepositoryUrl>https://github.com/linq2db/linq2db.EntityFrameworkCore</RepositoryUrl>
1310
<RepositoryType>git</RepositoryType>
1411

15-
<AppDesignerFolder>Properties</AppDesignerFolder>
16-
<LangVersion>8.0</LangVersion>
17-
<Nullable>disable</Nullable>
12+
<LangVersion>9.0</LangVersion>
13+
<Nullable>enable</Nullable>
1814
<WarningLevel>4</WarningLevel>
1915
<ErrorReport>prompt</ErrorReport>
20-
<NoWarn>1701;1591</NoWarn>
16+
<AnalysisLevel>preview</AnalysisLevel>
2117

2218
<AutoGenerateBindingRedirects>false</AutoGenerateBindingRedirects>
2319
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>

Build/linq2db.Tests.props

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project>
2+
<Import Project="linq2db.Default.props" />
3+
4+
<PropertyGroup>
5+
<TargetFrameworks>netcoreapp3.1</TargetFrameworks>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.0" />
10+
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0">
11+
<PrivateAssets>all</PrivateAssets>
12+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
13+
</PackageReference>
14+
<PackageReference Include="NUnit" Version="3.12.0" />
15+
</ItemGroup>
16+
17+
</Project>
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
// https://github.com/dotnet/runtime/blob/master/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs
6+
// https://raw.githubusercontent.com/dotnet/runtime/master/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs
7+
namespace System.Diagnostics.CodeAnalysis
8+
{
9+
/// <summary>Specifies that null is allowed as an input even if the corresponding type disallows it.</summary>
10+
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
11+
sealed class AllowNullAttribute : Attribute
12+
{ }
13+
14+
/// <summary>Specifies that null is disallowed as an input even if the corresponding type allows it.</summary>
15+
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
16+
sealed class DisallowNullAttribute : Attribute
17+
{ }
18+
19+
/// <summary>Specifies that an output may be null even if the corresponding type disallows it.</summary>
20+
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
21+
sealed class MaybeNullAttribute : Attribute
22+
{ }
23+
24+
/// <summary>Specifies that an output will not be null even if the corresponding type allows it. Specifies that an input argument was not null when the call returns.</summary>
25+
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
26+
sealed class NotNullAttribute : Attribute
27+
{ }
28+
29+
/// <summary>Specifies that when a method returns <see cref="ReturnValue"/>, the parameter may be null even if the corresponding type disallows it.</summary>
30+
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
31+
sealed class MaybeNullWhenAttribute : Attribute
32+
{
33+
/// <summary>Initializes the attribute with the specified return value condition.</summary>
34+
/// <param name="returnValue">
35+
/// The return value condition. If the method returns this value, the associated parameter may be null.
36+
/// </param>
37+
public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
38+
39+
/// <summary>Gets the return value condition.</summary>
40+
public bool ReturnValue { get; }
41+
}
42+
43+
/// <summary>Specifies that when a method returns <see cref="ReturnValue"/>, the parameter will not be null even if the corresponding type allows it.</summary>
44+
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
45+
sealed class NotNullWhenAttribute : Attribute
46+
{
47+
/// <summary>Initializes the attribute with the specified return value condition.</summary>
48+
/// <param name="returnValue">
49+
/// The return value condition. If the method returns this value, the associated parameter will not be null.
50+
/// </param>
51+
public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
52+
53+
/// <summary>Gets the return value condition.</summary>
54+
public bool ReturnValue { get; }
55+
}
56+
57+
/// <summary>Specifies that the output will be non-null if the named parameter is non-null.</summary>
58+
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
59+
sealed class NotNullIfNotNullAttribute : Attribute
60+
{
61+
/// <summary>Initializes the attribute with the associated parameter name.</summary>
62+
/// <param name="parameterName">
63+
/// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null.
64+
/// </param>
65+
public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName;
66+
67+
/// <summary>Gets the associated parameter name.</summary>
68+
public string ParameterName { get; }
69+
}
70+
71+
/// <summary>Applied to a method that will never return under any circumstance.</summary>
72+
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
73+
sealed class DoesNotReturnAttribute : Attribute
74+
{ }
75+
76+
/// <summary>Specifies that the method will not return if the associated Boolean parameter is passed the specified value.</summary>
77+
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
78+
sealed class DoesNotReturnIfAttribute : Attribute
79+
{
80+
/// <summary>Initializes the attribute with the specified parameter value.</summary>
81+
/// <param name="parameterValue">
82+
/// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to
83+
/// the associated parameter matches this value.
84+
/// </param>
85+
public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue;
86+
87+
/// <summary>Gets the condition parameter value.</summary>
88+
public bool ParameterValue { get; }
89+
}
90+
91+
/// <summary>Specifies that the method or property will ensure that the listed field and property members have not-null values.</summary>
92+
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
93+
sealed class MemberNotNullAttribute : Attribute
94+
{
95+
/// <summary>Initializes the attribute with a field or property member.</summary>
96+
/// <param name="member">
97+
/// The field or property member that is promised to be not-null.
98+
/// </param>
99+
public MemberNotNullAttribute(string member) => Members = new[] { member };
100+
101+
/// <summary>Initializes the attribute with the list of field and property members.</summary>
102+
/// <param name="members">
103+
/// The list of field and property members that are promised to be not-null.
104+
/// </param>
105+
public MemberNotNullAttribute(params string[] members)
106+
=> Members = members;
107+
108+
/// <summary>Gets field or property member names.</summary>
109+
public string[] Members { get; }
110+
}
111+
112+
/// <summary>Specifies that the method or property will ensure that the listed field and property members have not-null values when returning with the specified return value condition.</summary>
113+
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
114+
sealed class MemberNotNullWhenAttribute : Attribute
115+
{
116+
/// <summary>Initializes the attribute with the specified return value condition and a field or property member.</summary>
117+
/// <param name="returnValue">
118+
/// The return value condition. If the method returns this value, the associated parameter will not be null.
119+
/// </param>
120+
/// <param name="member">
121+
/// The field or property member that is promised to be not-null.
122+
/// </param>
123+
public MemberNotNullWhenAttribute(bool returnValue, string member)
124+
{
125+
ReturnValue = returnValue;
126+
Members = new[] { member };
127+
}
128+
129+
/// <summary>Initializes the attribute with the specified return value condition and list of field and property members.</summary>
130+
/// <param name="returnValue">
131+
/// The return value condition. If the method returns this value, the associated parameter will not be null.
132+
/// </param>
133+
/// <param name="members">
134+
/// The list of field and property members that are promised to be not-null.
135+
/// </param>
136+
public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
137+
{
138+
ReturnValue = returnValue;
139+
Members = members;
140+
}
141+
142+
/// <summary>Gets the return value condition.</summary>
143+
public bool ReturnValue { get; }
144+
145+
/// <summary>Gets field or property member names.</summary>
146+
public string[] Members { get; }
147+
}
148+
}

Source/LinqToDB.EntityFrameworkCore/EFConnectionInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ public class EFConnectionInfo
1010
/// <summary>
1111
/// Gets or sets database connection instance.
1212
/// </summary>
13-
public DbConnection Connection { get; set; }
13+
public DbConnection? Connection { get; set; }
1414

1515
/// <summary>
1616
/// Gets or sets database connection string.
1717
/// </summary>
18-
public string ConnectionString { get; set; }
18+
public string? ConnectionString { get; set; }
1919
}
2020
}

Source/LinqToDB.EntityFrameworkCore/EFCoreMetadataReader.cs

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ namespace LinqToDB.EntityFrameworkCore
2828
/// </summary>
2929
internal class EFCoreMetadataReader : IMetadataReader
3030
{
31-
readonly IModel _model;
32-
private readonly RelationalSqlTranslatingExpressionVisitorDependencies _dependencies;
33-
private readonly IRelationalTypeMappingSource _mappingSource;
34-
private readonly ConcurrentDictionary<MemberInfo, EFCoreExpressionAttribute> _calculatedExtensions = new ConcurrentDictionary<MemberInfo, EFCoreExpressionAttribute>();
31+
readonly IModel? _model;
32+
private readonly RelationalSqlTranslatingExpressionVisitorDependencies? _dependencies;
33+
private readonly IRelationalTypeMappingSource? _mappingSource;
34+
private readonly ConcurrentDictionary<MemberInfo, EFCoreExpressionAttribute?> _calculatedExtensions = new ConcurrentDictionary<MemberInfo, EFCoreExpressionAttribute?>();
3535

36-
public EFCoreMetadataReader(IModel model, RelationalSqlTranslatingExpressionVisitorDependencies dependencies, IRelationalTypeMappingSource mappingSource)
36+
public EFCoreMetadataReader(IModel? model, RelationalSqlTranslatingExpressionVisitorDependencies? dependencies, IRelationalTypeMappingSource? mappingSource)
3737
{
3838
_model = model;
3939
_dependencies = dependencies;
@@ -107,7 +107,7 @@ public T[] GetAttributes<T>(Type type, bool inherit = true) where T : Attribute
107107
return Array.Empty<T>();
108108
}
109109

110-
static bool CompareProperty(MemberInfo property, MemberInfo memberInfo)
110+
static bool CompareProperty(MemberInfo? property, MemberInfo memberInfo)
111111
{
112112
if (property == memberInfo)
113113
return true;
@@ -126,13 +126,11 @@ static bool CompareProperty(MemberInfo property, MemberInfo memberInfo)
126126
return false;
127127
}
128128

129-
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "EF1001:Internal EF Core API usage.", Justification = "<Pending>")]
130129
static bool CompareProperty(IProperty property, MemberInfo memberInfo)
131130
{
132131
return CompareProperty(property.GetIdentifyingMemberInfo(), memberInfo);
133132
}
134133

135-
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "EF1001:Internal EF Core API usage.", Justification = "<Pending>")]
136134
public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = true) where T : Attribute
137135
{
138136
if (typeof(Expression).IsSameOrParentOf(type))
@@ -307,7 +305,7 @@ class SqlTransparentExpression : SqlExpression
307305
{
308306
public Expression Expression { get; }
309307

310-
public SqlTransparentExpression(Expression expression, RelationalTypeMapping typeMapping) : base(expression.Type, typeMapping)
308+
public SqlTransparentExpression(Expression expression, RelationalTypeMapping? typeMapping) : base(expression.Type, typeMapping)
311309
{
312310
Expression = expression;
313311
}
@@ -318,16 +316,16 @@ public override void Print(ExpressionPrinter expressionPrinter)
318316
}
319317
}
320318

321-
private Sql.ExpressionAttribute GetDbFunctionFromMethodCall(Type type, MethodInfo methodInfo)
319+
private Sql.ExpressionAttribute? GetDbFunctionFromMethodCall(Type type, MethodInfo methodInfo)
322320
{
323321
if (_dependencies == null || _model == null)
324322
return null;
325323

326-
methodInfo = (MethodInfo) type.GetMemberEx(methodInfo) ?? methodInfo;
324+
methodInfo = (MethodInfo?) type.GetMemberEx(methodInfo) ?? methodInfo;
327325

328326
var found = _calculatedExtensions.GetOrAdd(methodInfo, mi =>
329327
{
330-
EFCoreExpressionAttribute result = null;
328+
EFCoreExpressionAttribute? result = null;
331329

332330
if (!methodInfo.IsGenericMethodDefinition && !mi.GetCustomAttributes<Sql.ExpressionAttribute>().Any())
333331
{
@@ -357,16 +355,16 @@ private Sql.ExpressionAttribute GetDbFunctionFromMethodCall(Type type, MethodInf
357355
return found;
358356
}
359357

360-
private Sql.ExpressionAttribute GetDbFunctionFromProperty(Type type, PropertyInfo propInfo)
358+
private Sql.ExpressionAttribute? GetDbFunctionFromProperty(Type type, PropertyInfo propInfo)
361359
{
362360
if (_dependencies == null || _model == null)
363361
return null;
364362

365-
propInfo = (PropertyInfo) type.GetMemberEx(propInfo) ?? propInfo;
363+
propInfo = (PropertyInfo?) type.GetMemberEx(propInfo) ?? propInfo;
366364

367365
var found = _calculatedExtensions.GetOrAdd(propInfo, mi =>
368366
{
369-
EFCoreExpressionAttribute result = null;
367+
EFCoreExpressionAttribute? result = null;
370368

371369
if ((propInfo.GetMethod?.IsStatic != true)
372370
&& !(mi is DynamicColumnInfo)
@@ -390,7 +388,7 @@ private Sql.ExpressionAttribute GetDbFunctionFromProperty(Type type, PropertyInf
390388

391389
private static EFCoreExpressionAttribute ConvertToExpressionAttribute(MemberInfo memberInfo, Expression newExpression, Expression[] parameters)
392390
{
393-
string PrepareExpressionText(Expression expr)
391+
string PrepareExpressionText(Expression? expr)
394392
{
395393
var idx = Array.IndexOf(parameters, expr);
396394
if (idx >= 0)

Source/LinqToDB.EntityFrameworkCore/EFProviderInfo.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,16 @@ public class EFProviderInfo
1313
/// <summary>
1414
/// Gets or sets database connection instance.
1515
/// </summary>
16-
public DbConnection Connection { get; set; }
16+
public DbConnection? Connection { get; set; }
1717

1818
/// <summary>
1919
/// Gets or sets EF.Core context instance.
2020
/// </summary>
21-
public DbContext Context { get; set; }
21+
public DbContext? Context { get; set; }
2222

2323
/// <summary>
2424
/// Gets or sets EF.Core context options instance.
2525
/// </summary>
26-
public IDbContextOptions Options { get; set; }
26+
public IDbContextOptions? Options { get; set; }
2727
}
2828
}

0 commit comments

Comments
 (0)