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

Commit e63148c

Browse files
authored
Merge pull request #176 from linq2db/version6
Release 6.2.0
2 parents 30945f9 + ea55615 commit e63148c

File tree

9 files changed

+162
-11
lines changed

9 files changed

+162
-11
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>6.1.0</Version>
3+
<Version>6.2.0</Version>
44

55
<Authors>Svyatoslav Danyliv, Igor Tkachev, Dmitry Lukashenko, Ilya Chudin</Authors>
66
<Product>Linq to DB</Product>

Directory.Packages.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
<PackageVersion Include="NUnit" Version="3.13.2" />
66
<PackageVersion Include="FluentAssertions" Version="5.10.3" />
77

8-
<PackageVersion Include="linq2db" Version="3.4.3" />
9-
<PackageVersion Include="linq2db.Tools" Version="3.4.3" />
8+
<PackageVersion Include="linq2db" Version="3.4.4" />
9+
<PackageVersion Include="linq2db.Tools" Version="3.4.4" />
1010

1111
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="1.0.0" />
1212

Source/LinqToDB.EntityFrameworkCore/EFCoreMetadataReader.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,24 @@ public T[] GetAttributes<T>(Type type, bool inherit = true) where T : Attribute
112112
if (tableAttribute != null)
113113
return new[] { (T)(Attribute)new TableAttribute(tableAttribute.Name) { Schema = tableAttribute.Schema } };
114114
}
115+
else if (_model != null && typeof(T) == typeof(InheritanceMappingAttribute))
116+
{
117+
if (et != null)
118+
{
119+
var derivedEntities = _model.GetEntityTypes().Where(e => e.BaseType == et && e.GetDiscriminatorValue() != null).ToList();
120+
121+
return
122+
derivedEntities.Select(e =>
123+
(T)(Attribute)new InheritanceMappingAttribute
124+
{
125+
Type = e.ClrType,
126+
Code = e.GetDiscriminatorValue()
127+
}
128+
)
129+
.ToArray();
130+
}
131+
132+
}
115133

116134
return Array.Empty<T>();
117135
}
@@ -174,7 +192,7 @@ static DataType DbTypeToDataType(DbType dbType)
174192
_ => DataType.Undefined
175193
};
176194
}
177-
195+
178196
public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = true) where T : Attribute
179197
{
180198
if (typeof(Expression).IsSameOrParentOf(type))
@@ -187,9 +205,11 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru
187205
{
188206
var props = et.GetProperties();
189207
var prop = props.FirstOrDefault(p => CompareProperty(p, memberInfo));
190-
208+
191209
if (prop != null)
192210
{
211+
var discriminator = et.FindDiscriminatorProperty();
212+
193213
var isPrimaryKey = prop.IsPrimaryKey();
194214
var primaryKeyOrder = 0;
195215
if (isPrimaryKey)
@@ -255,6 +275,7 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru
255275
IsPrimaryKey = isPrimaryKey,
256276
PrimaryKeyOrder = primaryKeyOrder,
257277
IsIdentity = isIdentity,
278+
IsDiscriminator = discriminator == prop
258279
}
259280
};
260281
}

Source/LinqToDB.EntityFrameworkCore/Internal/LinqToDBForEFQueryProvider.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ IEnumerator IEnumerable.GetEnumerator()
160160
/// <returns>Query result as <see cref="IAsyncEnumerable{T}"/>.</returns>
161161
public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken)
162162
{
163-
return QueryProvider.ExecuteAsyncEnumerable<T>(Expression, cancellationToken).Result.GetAsyncEnumerator(cancellationToken);
163+
return Task.Run(() => QueryProvider.ExecuteAsyncEnumerable<T>(Expression, cancellationToken),
164+
cancellationToken).Result.GetAsyncEnumerator(cancellationToken);
164165
}
165166

166167
/// <summary>

Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFTools.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ public static MappingSchema GetMappingSchema(
231231
/// <param name="ctx">Optional DbContext instance.</param>
232232
/// <param name="model">EF Core data model instance.</param>
233233
/// <returns>Transformed expression.</returns>
234-
public static Expression TransformExpression(Expression expression, IDataContext dc, DbContext? ctx, IModel? model)
234+
public static Expression TransformExpression(Expression expression, IDataContext? dc, DbContext? ctx, IModel? model)
235235
{
236236
return Implementation.TransformExpression(expression, dc, ctx, model);
237237
}

Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFToolsDataConnection.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,11 @@ private void OnEntityCreatedHandler(EntityCreatedEventArgs args)
241241
var assignExpr = Expression.Assign(variable, Expression.Convert(objParam, entityType.ClrType));
242242

243243
var key = entityType.GetKeys().FirstOrDefault();
244+
if (key == null)
245+
return null;
244246

245247
var arrayExpr = key.Properties.Where(p => p.PropertyInfo != null || p.FieldInfo != null).Select(p =>
246-
Expression.Convert(Expression.MakeMemberAccess(variable, p.PropertyInfo ?? (MemberInfo)p.FieldInfo),
248+
Expression.Convert(Expression.MakeMemberAccess(variable, p.PropertyInfo ?? (MemberInfo)p.FieldInfo!),
247249
typeof(object)))
248250
.ToArray();
249251

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
using System;
2+
using System.Linq;
3+
using Microsoft.EntityFrameworkCore;
4+
5+
namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Inheritance
6+
{
7+
public abstract class BlogBase
8+
{
9+
public int Id { get; set; }
10+
public string BlogType { get; set; } = null!;
11+
}
12+
13+
public class Blog : BlogBase
14+
{
15+
public string Url { get; set; } = null!;
16+
}
17+
18+
public class RssBlog : BlogBase
19+
{
20+
public string Url { get; set; } = null!;
21+
}
22+
23+
public abstract class ShadowBlogBase
24+
{
25+
public int Id { get; set; }
26+
public string BlogType { get; set; } = null!;
27+
}
28+
29+
public class ShadowBlog : ShadowBlogBase
30+
{
31+
public string Url { get; set; } = null!;
32+
}
33+
34+
public class ShadowRssBlog : ShadowBlogBase
35+
{
36+
public string Url { get; set; } = null!;
37+
}
38+
39+
public interface IVersionable
40+
{
41+
int Id { get; set; }
42+
int? ParentVersionId { get; set; }
43+
}
44+
45+
public class InheritanceContext : DbContext
46+
{
47+
public InheritanceContext(DbContextOptions options) : base(options)
48+
{
49+
}
50+
51+
private void VersionEntity()
52+
{
53+
ChangeTracker.DetectChanges();
54+
var modifiedEntries = ChangeTracker.Entries().Where(e => e.State == EntityState.Modified && e.Entity is IVersionable);
55+
56+
foreach (var modifiedEntry in modifiedEntries)
57+
{
58+
var cloned = (IVersionable)Activator.CreateInstance(modifiedEntry.Entity.GetType());
59+
modifiedEntry.CurrentValues.SetValues(cloned);
60+
61+
// rollback
62+
modifiedEntry.CurrentValues.SetValues(modifiedEntry.OriginalValues);
63+
64+
cloned.Id = 0;
65+
cloned.ParentVersionId = ((IVersionable)(modifiedEntry).Entity).Id;
66+
67+
Add((object)cloned);
68+
}
69+
}
70+
71+
public override int SaveChanges()
72+
{
73+
return base.SaveChanges();
74+
}
75+
76+
protected override void OnModelCreating(ModelBuilder modelBuilder)
77+
{
78+
modelBuilder.Entity<BlogBase>()
79+
.HasDiscriminator(b => b.BlogType)
80+
.HasValue<Blog>("blog_base")
81+
.HasValue<RssBlog>("blog_rss");
82+
83+
modelBuilder.Entity<BlogBase>()
84+
.Property(e => e.BlogType)
85+
.HasColumnName("BlogType")
86+
.HasMaxLength(200);
87+
88+
modelBuilder.Entity<Blog>()
89+
.Property(b => b.Url)
90+
.HasColumnName("Url");
91+
92+
modelBuilder.Entity<RssBlog>()
93+
.Property(b => b.Url)
94+
.HasColumnName("Url");
95+
96+
modelBuilder.Entity<Blog>().ToTable("Blogs");
97+
modelBuilder.Entity<RssBlog>().ToTable("Blogs");
98+
99+
/////
100+
101+
modelBuilder.Entity<ShadowBlogBase>()
102+
.HasDiscriminator()
103+
.HasValue<ShadowBlog>("blog_base")
104+
.HasValue<ShadowRssBlog>("blog_rss");
105+
106+
modelBuilder.Entity<ShadowBlogBase>()
107+
.Property(e => e.BlogType)
108+
.HasColumnName("BlogType")
109+
.HasMaxLength(200);
110+
111+
modelBuilder.Entity<ShadowBlog>()
112+
.Property(b => b.Url)
113+
.HasColumnName("Url");
114+
115+
modelBuilder.Entity<ShadowRssBlog>()
116+
.Property(b => b.Url)
117+
.HasColumnName("Url");
118+
119+
modelBuilder.Entity<ShadowBlog>().ToTable("ShadowBlogs");
120+
modelBuilder.Entity<ShadowRssBlog>().ToTable("ShadowBlogs");
121+
}
122+
123+
public DbSet<BlogBase> Blogs { get; set; } = null!;
124+
public DbSet<ShadowBlogBase> ShadowBlogs { get; set; } = null!;
125+
}
126+
127+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public void ConfigureEntityFilter<TEntity>(ModelBuilder builder)
7777
{
7878
NorthwindContext? obj = null;
7979

80-
builder.Entity<TEntity>().HasQueryFilter(e => !obj!.IsSoftDeleteFilterEnabled || !e.IsDeleted);
80+
builder.Entity<TEntity>().HasQueryFilter(e => !obj!.IsSoftDeleteFilterEnabled || !e.IsDeleted || !EF.Property<bool>(e, "IsDeleted"));
8181
}
8282

8383
public bool IsFilterProducts { get; set; }

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: 6.1.0
5-
nugetVersion: 6.1.0
4+
assemblyVersion: 6.2.0
5+
nugetVersion: 6.2.0
66
artifact_nugets: 'nugets'
77

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

0 commit comments

Comments
 (0)