Skip to content

Unnecessary "INNER JOIN" when using a navigation property #207

@inosyryev

Description

@inosyryev

LINQ

from engineeringConnector in repository.EngineeringConnectors
where engineeringConnector.EngineeringCircuits.Any(x => ids.Contains(x.EngineeringCircuitID))
select new { engineeringConnector.EngineeringConnectorID };

SQL

SELECT
    [engineeringConnector].[EngineeringConnectorID]
FROM
    [EngineeringConnector] [engineeringConnector]
        INNER JOIN [EngineeringCircuitEnd] [t1] ON [engineeringConnector].[EngineeringConnectorID] = [t1].[EngineeringConnectorID]
WHERE
    EXISTS(
        SELECT
            *
        FROM
            [EngineeringCircuitEnd] [c]
        WHERE
            [engineeringConnector].[EngineeringConnectorID] = [c].[EngineeringConnectorID] AND
            [c].[EngineeringCircuitID] IN (4094837, 4095281, 4097457)
    )

Problem

FROM should not have INNER JOIN [EngineeringCircuitEnd] [t1] ON [engineeringConnector].[EngineeringConnectorID] = [t1].[EngineeringConnectorID]
Usage of this expression makes a performance impact and generates duplicates for [EngineeringConnector]

Generated expression file

//---------------------------------------------------------------------------------------------------
// This code was generated by BLToolkit.
//---------------------------------------------------------------------------------------------------
using System;
using System.Linq.Expressions;

using NUnit.Framework;

namespace SPX.DEF.FromTo.UnitTest
{
    [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    class <>c__DisplayClassa
    {
        public Int64[] ids;
    }
}

namespace SPX.GCIS.Data.Sql
{
    [BLToolkit.DataAccess.TableNameAttribute(Name = "EngineeringCircuitEnd")]
    public class EngineeringCircuitEndRecord
    {
        [BLToolkit.DataAccess.PrimaryKeyAttribute((Int32)1)]
        [BLToolkit.DataAccess.IdentityAttribute()]
        public Int64 EngineeringCircuitID { get; set; }
    }
}

namespace SPX.GCIS.Data.Sql
{
    [BLToolkit.DataAccess.TableNameAttribute(Name = "EngineeringConnector")]
    public class EngineeringConnectorRecord
    {
        [BLToolkit.Mapping.AssociationAttribute(ThisKey = "EngineeringConnectorID", OtherKey = "EngineeringConnectorID", CanBeNull = False)]
        public System.Collections.Generic.List<SPX.GCIS.Data.Sql.EngineeringCircuitEndRecord> EngineeringCircuits { get; set; }

        [BLToolkit.DataAccess.PrimaryKeyAttribute((Int32)1)]
        [BLToolkit.DataAccess.IdentityAttribute()]
        public Int64 EngineeringConnectorID { get; set; }
    }
}

namespace Data.Linq
{
    [TestFixture]
    public class UserTest : TestBase
    {
        [Test]
        public void Test()
        {
            // Table(EngineeringConnectorRecord).Where(engineeringConnector => engineeringConnector.EngineeringCircuits.Any(x => value(SPX.DEF.FromTo.UnitTest.BlToolkitTesting+<>c__DisplayClassa).ids.Contains(x.EngineeringCircuitID))).Select(engineeringConnector => new <>f__AnonymousType9`1(EngineeringConnectorID = engineeringConnector.EngineeringConnectorID))
            ForEachProvider(db =>
                Table(EngineeringConnectorRecord)
                    .Where<SPX.GCIS.Data.Sql.EngineeringConnectorRecord>(
                        (SPX.GCIS.Data.Sql.EngineeringConnectorRecord engineeringConnector) => engineeringConnector.EngineeringCircuits
                            .Any<SPX.GCIS.Data.Sql.EngineeringCircuitEndRecord>(
                                (SPX.GCIS.Data.Sql.EngineeringCircuitEndRecord x) => value(SPX.DEF.FromTo.UnitTest.BlToolkitTesting+<>c__DisplayClassa).ids
                                    .Contains<Int64>(
                                        x.EngineeringCircuitID)))
                    .Select(
                        (SPX.GCIS.Data.Sql.EngineeringConnectorRecord engineeringConnector) => new { EngineeringConnectorID = engineeringConnector.EngineeringConnectorID }}));
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions