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

Commit f6581ab

Browse files
authored
Fix for #73. Corrected navigation property mapping. (#74)
* Re-enabled logging. * Fix for #73. Corrected navigation property mapping.
1 parent 064c8f0 commit f6581ab

File tree

5 files changed

+153
-27
lines changed

5 files changed

+153
-27
lines changed

Source/LinqToDB.EntityFrameworkCore/EFCoreMetadataReader.cs

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -189,30 +189,16 @@ public T[] GetAttributes<T>(Type type, MemberInfo memberInfo, bool inherit = tru
189189
foreach (var navigation in navigations)
190190
{
191191
var fk = navigation.ForeignKey;
192-
if (fk.PrincipalEntityType == et)
193-
{
194-
var thisKey = string.Join(",", fk.PrincipalKey.Properties.Select(p => p.Name));
195-
var otherKey = string.Join(",", fk.Properties.Select(p => p.Name));
196-
associations.Add(new AssociationAttribute
197-
{
198-
ThisKey = thisKey,
199-
OtherKey = otherKey,
200-
CanBeNull = !fk.IsRequired,
201-
IsBackReference = false
202-
});
203-
}
204-
else
192+
193+
var thisKey = string.Join(",", fk.Properties.Select(p => p.Name));
194+
var otherKey = string.Join(",", fk.PrincipalKey.Properties.Select(p => p.Name));
195+
associations.Add(new AssociationAttribute
205196
{
206-
var thisKey = string.Join(",", fk.Properties.Select(p => p.Name));
207-
var otherKey = string.Join(",", fk.PrincipalKey.Properties.Select(p => p.Name));
208-
associations.Add(new AssociationAttribute
209-
{
210-
ThisKey = thisKey,
211-
OtherKey = otherKey,
212-
CanBeNull = !fk.IsRequired,
213-
IsBackReference = true
214-
});
215-
}
197+
ThisKey = thisKey,
198+
OtherKey = otherKey,
199+
CanBeNull = !fk.IsRequired,
200+
IsBackReference = fk.PrincipalEntityType != et
201+
});
216202
}
217203

218204
return associations.Select(a => (T)(Attribute)a).ToArray();

Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFTools.cs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Concurrent;
33
using System.Data.Common;
4+
using System.Diagnostics;
45
using System.Linq;
56
using System.Linq.Expressions;
67
using System.Reflection;
@@ -284,7 +285,9 @@ public static DataConnection CreateLinqToDbConnection(this DbContext context,
284285

285286
var logger = CreateLogger(info.Options);
286287
if (logger != null)
287-
dc.OnTraceConnection = t => Implementation.LogConnectionTrace(t, logger);
288+
{
289+
EnableTracing(dc, logger);
290+
}
288291

289292
var dependencies = context.GetService<RelationalSqlTranslatingExpressionVisitorDependencies>();
290293
var mappingSource = context.GetService<IRelationalTypeMappingSource>();
@@ -296,6 +299,15 @@ public static DataConnection CreateLinqToDbConnection(this DbContext context,
296299
return dc;
297300
}
298301

302+
private static TraceSwitch _defaultTraceSwitch =
303+
new TraceSwitch("DataConnection", "DataConnection trace switch", TraceLevel.Info.ToString());
304+
305+
static void EnableTracing(DataConnection dc, ILogger logger)
306+
{
307+
dc.OnTraceConnection = t => Implementation.LogConnectionTrace(t, logger);
308+
dc.TraceSwitchConnection = _defaultTraceSwitch;
309+
}
310+
299311
public static ILogger CreateLogger(IDbContextOptions options)
300312
{
301313
return Implementation.CreateLogger(options);
@@ -356,7 +368,9 @@ public static IDataContext CreateLinqToDbContext(this DbContext context,
356368
dc.AddMappingSchema(mappingSchema);
357369

358370
if (logger != null)
359-
dc.OnTraceConnection = t => Implementation.LogConnectionTrace(t, logger);
371+
{
372+
EnableTracing(dc, logger);
373+
}
360374

361375
return dc;
362376
}
@@ -377,8 +391,11 @@ public static DataConnection CreateLinq2DbConnectionDetached([JetBrains.Annotati
377391

378392
var dc = new LinqToDBForEFToolsDataConnection(context, dataProvider, connectionInfo.ConnectionString, context.Model, TransformExpression);
379393
var logger = CreateLogger(info.Options);
394+
380395
if (logger != null)
381-
dc.OnTraceConnection = t => Implementation.LogConnectionTrace(t, logger);
396+
{
397+
EnableTracing(dc, logger);
398+
}
382399

383400
var dependencies = context.GetService<RelationalSqlTranslatingExpressionVisitorDependencies>();
384401
var mappingSource = context.GetService<IRelationalTypeMappingSource>();
@@ -472,7 +489,9 @@ public static DataConnection CreateLinqToDbConnection(this DbContextOptions opti
472489

473490
var logger = CreateLogger(info.Options);
474491
if (logger != null)
475-
dc.OnTraceConnection = t => Implementation.LogConnectionTrace(t, logger);
492+
{
493+
EnableTracing(dc, logger);
494+
}
476495

477496
if (model != null)
478497
{
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using System.Linq;
2+
using LinqToDB.EntityFrameworkCore.BaseTests;
3+
using LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind;
4+
using Microsoft.EntityFrameworkCore;
5+
using NUnit.Framework;
6+
using NUnit.Framework.Constraints;
7+
8+
namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests
9+
{
10+
[TestFixture]
11+
public class IssueTests : TestsBase
12+
{
13+
private DbContextOptions<IssueContext> _options;
14+
private bool _created;
15+
16+
public IssueTests()
17+
{
18+
var optionsBuilder = new DbContextOptionsBuilder<IssueContext>();
19+
//new SqlServerDbContextOptionsBuilder(optionsBuilder);
20+
21+
optionsBuilder.UseSqlServer("Server=.;Database=IssuesEFCore;Integrated Security=SSPI");
22+
optionsBuilder.UseLoggerFactory(TestUtils.LoggerFactory);
23+
24+
_options = optionsBuilder.Options;
25+
}
26+
27+
private IssueContext CreateContext()
28+
{
29+
var ctx = new IssueContext(_options);
30+
31+
if (!_created)
32+
{
33+
ctx.Database.EnsureCreated();
34+
_created = true;
35+
}
36+
return ctx;
37+
}
38+
39+
40+
[Test]
41+
public void Issue73Test()
42+
{
43+
using var ctx = CreateContext();
44+
45+
var q = ctx.Issue73Entities
46+
.Where(x => x.Name == "Name1_3")
47+
.Select(x => x.Parent.Name + ">" + x.Name);
48+
49+
var efItems = q.ToList();
50+
var linq2dbItems = q.ToLinqToDB().ToList();
51+
52+
AreEqual(efItems, linq2dbItems);
53+
}
54+
55+
}
56+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.Collections.Generic;
2+
3+
namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.IssueModel
4+
{
5+
public sealed class Issue73Entity
6+
{
7+
public int Id { get; set; }
8+
9+
public int? ParentId { get; set; }
10+
11+
public Issue73Entity Parent { get; set; }
12+
public List<Issue73Entity> Childs { get; set; }
13+
14+
public string Name { get; set; }
15+
}
16+
17+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System.Reflection;
2+
using LinqToDB.EntityFrameworkCore.BaseTests.Models.Northwind;
3+
using LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.IssueModel;
4+
using LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind.Mapping;
5+
using LinqToDB.Expressions;
6+
using LinqToDB.Extensions;
7+
using Microsoft.EntityFrameworkCore;
8+
9+
namespace LinqToDB.EntityFrameworkCore.SqlServer.Tests.Models.Northwind
10+
{
11+
public class IssueContext : DbContext
12+
{
13+
public DbSet<Issue73Entity> Issue73Entities { get; set; }
14+
15+
public IssueContext(DbContextOptions options) : base(options)
16+
{
17+
18+
}
19+
20+
protected override void OnModelCreating(ModelBuilder modelBuilder)
21+
{
22+
modelBuilder.Entity<Issue73Entity>(b =>
23+
{
24+
b.HasKey(x => new { x.Id });
25+
26+
b.HasOne(x => x.Parent)
27+
.WithMany(x => x.Childs)
28+
.HasForeignKey(x => new { x.ParentId })
29+
.HasPrincipalKey(x => new { x.Id });
30+
31+
b.HasData(new[]
32+
{
33+
new Issue73Entity
34+
{
35+
Id = 2,
36+
Name = "Name1_2",
37+
},
38+
new Issue73Entity
39+
{
40+
Id = 3,
41+
Name = "Name1_3",
42+
ParentId = 2
43+
},
44+
});
45+
});
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)