linq2db / linq2db.EntityFrameworkCore

Bring power of Linq To DB to Entity Framework Core projects
MIT License
462 stars 38 forks source link

Different results (and SQL queries) by SingleAsyncEF and SingleAsyncLinqToDB with self-referenced entity #73

Closed parus95 closed 3 years ago

parus95 commented 3 years ago

A very simple query with an entity referencing itself gives an incorrect result (the relation unfolds in the opposite direction).

My database: PostgreSQL

Software versions

    <TargetFramework>netcoreapp3.1</TargetFramework>
    <PackageReference Include="linq2db.EntityFrameworkCore" Version="3.7.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.9" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.9"/>
    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.4" />

My entity:

        public sealed class TestEntity
        {
            public int Id { get; set; }

            public int? ParentId { get; set; }

            public TestEntity Parent { get; set; }
            public List<TestEntity> Childs { get; set; }

            public string Name { get; set; }
        }

Configuration

modelBuilder.Entity<TestEntity>(b =>
{
    b.HasKey(x => new { x.Id });

    b.HasOne(x => x.Parent)
        .WithMany(x => x.Childs)
        .HasForeignKey(x => new { x.ParentId })
        .HasPrincipalKey(x => new { x.Id });

    b.HasData(new[]
    {
        new TestEntity
        {
            Id=2,
            Name = "Name1_2",
        },
        new TestEntity
        {
            Id=3,
            Name = "Name1_3",
            ParentId=2
        },
    });
});

query:

var q = dbContext.TestEntities
    .Where(x => x.Name == "Name1_3")
    .Select(x => x.Parent.Name + ">" + x.Name);

EF result (correct):

var efResult = await q.SingleAsyncEF();
/*
* SQL generated by EF Core
SELECT (t0."Name" || '>') || t."Name"
FROM "TestEntities" AS t
LEFT JOIN "TestEntities" AS t0 ON t."ParentId" = t0."Id"
WHERE t."Name" = 'Name1_3'
LIMIT 2
*/

// Prints: Name1_2>Name1_3
Console.WriteLine("EF result: " + efResult);

linq2db.EntityFrameworkCore result (incorrect):


var l2dbResult = await q.SingleAsyncLinqToDB();

var lq = q.ToLinqToDB();
/* SQL generated by linq2db
SELECT
        "a_Parent"."Name",
        x."Name"
FROM
        "TestEntities" x
        -- !!! Error on next line !!!!
                LEFT JOIN "TestEntities" "a_Parent" ON x."Id" = "a_Parent"."ParentId"
WHERE
        x."Name" = 'Name1_3'
LIMIT $1
*/
// Prints: ">Name1_3"
Console.WriteLine("L2DB result: " + l2dbResult);

Test project attached to current issue:

TestAppToSend.zip

sdanyliv commented 3 years ago

Thanks for reporting. Will check that.