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

Commit b2497fd

Browse files
authored
Merge pull request #53 from linq2db/master
Release 3.3.0
2 parents 47c18f9 + f9c108f commit b2497fd

File tree

9 files changed

+72
-18
lines changed

9 files changed

+72
-18
lines changed

Build/linq2db.Default.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<PropertyGroup>
3-
<Version>3.2.0</Version>
3+
<Version>3.3.0</Version>
44

55
<Description>Allows to execute Linq to DB (linq2db) queries in Entity Framework Core DbContext.</Description>
66
<Title>Linq to DB (linq2db) extensions for Entity Framework Core</Title>

NuGet/linq2db.EntityFrameworkCore.nuspec

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

README.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,20 @@
1515
* NuGet [![NuGet](https://img.shields.io/nuget/vpre/linq2db.EntityFrameworkCore.svg)](https://www.nuget.org/packages/linq2db.EntityFrameworkCore)
1616
* Azure Artifacts [![MyGet](https://img.shields.io/badge/azure-download-yellowgreen)](https://dev.azure.com/linq2db/linq2db/_packaging?_a=package&feed=linq2db&view=versions&package=linq2db.EntityFrameworkCore&protocolType=NuGet) ([feed]( https://pkgs.dev.azure.com/linq2db/linq2db/_packaging/linq2db/nuget/v3/index.json))
1717

18+
# Unique features
19+
* Fast Eager Loading (incomparable faster on massive `Include` query)
20+
* Global Query Filters optimization
21+
* Better SQL optimization
22+
* [Use CTE in LINQ queries](https://linq2db.github.io/articles/sql/CTE.html)
23+
* [MERGE statement support](https://linq2db.github.io/articles/sql/merge/Merge-API-Description.html)
24+
* Table hints
25+
* [Full Window functions support](https://linq2db.github.io/articles/sql/Window-Functions-(Analytic-Functions).html)
26+
* Fast [BulkCopy](https://linq2db.github.io/articles/sql/Bulk-Copy.html) of millions records
27+
* Native SQL operations for updating, deleting, inserting records via LINQ query
28+
* Temporary Tables support
29+
* Cross Database/Linked Server queries.
30+
* Full Text Search extensions
31+
* A lot of extensions to cover ANSI SQL
1832
# How to use
1933

2034
In your code you need to initialize integration using following call:
@@ -141,10 +155,9 @@ Below is a list of providers, that should work right now:
141155
- SQL Server CE
142156

143157
# Know limitations
144-
- No Eager loading
145158
- No Lazy loading
146159
- No way to work with in-memory database
147-
- `Include` function supported with limitations
160+
- `HasConversion` for properties currently not supported. Can be done via linq2db's `MappingSchema.Default.SetConverter()` function.
148161

149162
# Help! It doesn't work!
150163

Source/LinqToDB.EntityFrameworkCore/EFCoreMetadataReader.cs

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ static bool CompareProperty(MemberInfo property, MemberInfo memberInfo)
111111
{
112112
if (property == memberInfo)
113113
return true;
114+
115+
if (property == null)
116+
return false;
114117

115118
if (memberInfo.DeclaringType?.IsAssignableFrom(property.DeclaringType) == true
116119
&& memberInfo.Name == property.Name
@@ -214,9 +217,8 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru
214217

215218
return associations.Select(a => (T)(Attribute)a).ToArray();
216219
}
217-
}
218-
219-
if (typeof(T) == typeof(Sql.ExpressionAttribute))
220+
}
221+
else if (typeof(T) == typeof(Sql.ExpressionAttribute))
220222
{
221223
// Search for translator first
222224
if (_dependencies != null)
@@ -260,10 +262,47 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru
260262
}).ToArray();
261263
}
262264
}
265+
else if (typeof(T) == typeof(ValueConverterAttribute))
266+
{
267+
var et = _model?.FindEntityType(type);
268+
if (et != null)
269+
{
270+
var props = et.GetProperties();
271+
var prop = props.FirstOrDefault(p => CompareProperty(p, memberInfo));
272+
273+
var converter = prop?.GetValueConverter();
274+
if (converter != null)
275+
{
276+
var valueConverterAttribute = new ValueConverterAttribute
277+
{
278+
ValueConverter = new ValueConverter(converter.ConvertToProviderExpression,
279+
converter.ConvertFromProviderExpression, false)
280+
};
281+
return new T[] { (T) (Attribute) valueConverterAttribute };
282+
}
283+
}
284+
}
263285

264286
return Array.Empty<T>();
265287
}
266288

289+
class ValueConverter : IValueConverter
290+
{
291+
public ValueConverter(
292+
LambdaExpression convertToProviderExpression,
293+
LambdaExpression convertFromProviderExpression, bool handlesNulls)
294+
{
295+
FromProviderExpression = convertFromProviderExpression;
296+
ToProviderExpression = convertToProviderExpression;
297+
HandlesNulls = handlesNulls;
298+
}
299+
300+
public bool HandlesNulls { get; }
301+
public LambdaExpression FromProviderExpression { get; }
302+
public LambdaExpression ToProviderExpression { get; }
303+
304+
}
305+
267306
class SqlTransparentExpression : SqlExpression
268307
{
269308
public Expression Expression { get; }
@@ -329,7 +368,9 @@ private Sql.ExpressionAttribute GetDbFunctionFromProperty(Type type, PropertyInf
329368
{
330369
EFCoreExpressionAttribute result = null;
331370

332-
if ((propInfo.GetMethod?.IsStatic != true) && !mi.GetCustomAttributes<Sql.ExpressionAttribute>().Any())
371+
if ((propInfo.GetMethod?.IsStatic != true)
372+
&& !(mi is DynamicColumnInfo)
373+
&& !mi.GetCustomAttributes<Sql.ExpressionAttribute>().Any())
333374
{
334375
var objExpr = new SqlTransparentExpression(Expression.Constant(DefaultValue.GetValue(type), type), _mappingSource?.FindMapping(propInfo));
335376

Source/LinqToDB.EntityFrameworkCore/linq2db.EntityFrameworkCore.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
</PropertyGroup>
1010

1111
<ItemGroup>
12-
<PackageReference Include="linq2db" Version="3.0.0-rc.0" />
12+
<PackageReference Include="linq2db" Version="3.0.0-rc.1" />
1313
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.3" />
1414
</ItemGroup>
1515

Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/JsonConverTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ public void TestJsonConvert()
9090
{
9191
LinqToDBForEFTools.Initialize();
9292

93-
// converting from string, because usually JSON is stored as string, but it depends on DataProvider
94-
Mapping.MappingSchema.Default.SetConverter<string, LocalizedString>(v => JsonConvert.DeserializeObject<LocalizedString>(v));
95-
96-
// here we told linq2db how to pass converted value as DataParameter.
97-
Mapping.MappingSchema.Default.SetConverter<LocalizedString, DataParameter>(v => new DataParameter("", JsonConvert.SerializeObject(v), LinqToDB.DataType.NVarChar));
93+
// // converting from string, because usually JSON is stored as string, but it depends on DataProvider
94+
// Mapping.MappingSchema.Default.SetConverter<string, LocalizedString>(v => JsonConvert.DeserializeObject<LocalizedString>(v));
95+
//
96+
// // here we told linq2db how to pass converted value as DataParameter.
97+
// Mapping.MappingSchema.Default.SetConverter<LocalizedString, DataParameter>(v => new DataParameter("", JsonConvert.SerializeObject(v), LinqToDB.DataType.NVarChar));
9898

9999
using (var ctx = new JsonConvertContext(_options))
100100
{

Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/Models/Northwind/NorthwindContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ private void ConfigureGlobalQueryFilters(ModelBuilder builder)
5757
if (typeof(ISoftDelete).IsSameOrParentOf(entityType.ClrType))
5858
{
5959
var method = ConfigureEntityFilterMethodInfo.MakeGenericMethod(entityType.ClrType);
60-
method.Invoke(this, new object?[] { builder });
60+
method.Invoke(this, new object[] { builder });
6161
}
6262
}
6363
}

Tests/LinqToDB.EntityFrameworkCore.SqlServer.Tests/ToolsTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ private void SetIdentityInsert(DbContext ctx, string tableName, bool isOn)
5959
var str = $"SET IDENTITY_INSERT {tableName} " + (isOn ? "ON" : "OFF");
6060
try
6161
{
62-
ctx.Database.ExecuteSqlCommand(str);
62+
ctx.Database.ExecuteSqlRaw(str);
6363
}
6464
catch (Exception)
6565
{

azure-pipelines.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
variables:
22
solution: 'linq2db.EFCore.sln'
33
build_configuration: 'Release'
4-
assemblyVersion: 3.2.0
5-
nugetVersion: 3.2.0
4+
assemblyVersion: 3.3.0
5+
nugetVersion: 3.3.0
66
artifact_nugets: 'nugets'
77

88
# build on commits to important branches (master + release branches):

0 commit comments

Comments
 (0)