Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: use LINQ-provider from linq2db #11657

Closed
Kirill-Maurin opened this issue Apr 12, 2018 · 25 comments
Closed

Feature request: use LINQ-provider from linq2db #11657

Kirill-Maurin opened this issue Apr 12, 2018 · 25 comments
Labels
closed-no-further-action The issue is closed and no further action is planned.

Comments

@Kirill-Maurin
Copy link

Kirill-Maurin commented Apr 12, 2018

Сurrently LINQ-provider in EF Core is far from perfect.
But there is a production-ready alternative: linq2db
EF Core model can be tranlated to linq2db mapping scheme.
This will allow very cheap access to the following functionality:

  1. "Group by"
  2. Nested queries
  3. Extensions for easy implementation of any unsupported "out-of-box" DB-specific function or operation (like IP address comparison for PostgreSql)
  4. Bulk operations
  5. Many more different features

Also, EF Core team will be able to allocate more resources for the improvement of migrations, change tracker and other unique EF Core features

Now I use my own wrapper to transparently combine two ORM sharing one model

@ajcvickers
Copy link
Member

@Kirill-Maurin We are supportive of creating extensions that can be used with EF Core to enhance or replace some existing built-in part of the stack. To that end, we would be happy to work with the community on adding appropriate extension points to EF Core that can be used for such things. That being said, it would have to be a community driven effort, and the majority of the code should live externally to the EF Core repo.

With regard to the list of functionality that is "missing" could you be more specific on which parts are not working for you? It seems like the first three are implemented in 2.1, and #4 requires more than just changing the LINQ provider.

@ajcvickers ajcvickers added this to the Discussions milestone Apr 13, 2018
@Kirill-Maurin
Copy link
Author

Kirill-Maurin commented Apr 16, 2018

It seems like the first three are implemented in 2.1

Nested queries

07:14:11.3131|[1]|Entity Framework Core 2.1.0-preview1-28290 initialized 'PostgreSqlXYZContext' using provider 'Npgsql.EntityFrameworkCore.PostgreSQL' with options: None
07:14:11.6428|[1]|Opening connection to database 'XYZ' on server 'tcp://test:1234'.
07:14:12.1828|[12]|Opened connection to database 'XYZ' on server 'tcp://test:1234'.
07:14:12.1828|[12]|Beginning transaction with isolation level 'Snapshot'.
07:14:12.4002|[7]|Compiling query model: 
'from X p in DbSet<X>
select new <>f__AnonymousType4<byte[], string, int, string>(
    [p].XId, 
    [p].IP, 
    [p].Port, 

        (from IP2Country c in DbSet<IP2Country>
        where int [c].From.CompareTo([p].IP) <= 0
        order by [c].From desc
        select [c])
        .Take(1)
        .FirstOrDefault().Country
)'
07:14:12.4803|[7]|Optimized query model: 
'from X p in DbSet<X>
select new <>f__AnonymousType4<byte[], string, int, string>(
    [p].XId, 
    [p].IP, 
    [p].Port, 

        (from IP2Country c in DbSet<IP2Country>
        where int [c].From.CompareTo([p].IP) <= 0
        order by [c].From desc
        select [c].Country)
        .Take(1)
        .FirstOrDefault()
)'
07:14:12.6714|[7]|(QueryContext queryContext) => IEnumerable<<>f__AnonymousType4<byte[], string, int, string>> _InterceptExceptions(
    source: IEnumerable<<>f__AnonymousType4<byte[], string, int, string>> _ShapedQuery(
        queryContext: queryContext, 
        shaperCommandContext: SelectExpression: 
            SELECT "p"."XId", "p"."IP", "p"."Port", (
                SELECT "t".*
                FROM (
                    SELECT "c"."Country"
                    FROM "IP2Country" AS "c"
                    WHERE "c"."From" <= "p"."IP"
                    ORDER BY "c"."From" DESC
                    LIMIT 1
                ) AS "t"
                ORDER BY "t"."From" DESC
                LIMIT 1
            ) AS "Country"
            FROM "Xs" AS "p", 
        shaper: TypedProjectionShaper<ValueBufferShaper, ValueBuffer, <>f__AnonymousType4<byte[], string, int, string>>), 
    contextType: XYZ.PostgreSql.PostgreSqlXYZContext, 
    logger: DiagnosticsLogger<Query>, 
    queryContext: queryContext)
07:14:12.7013|[7]|Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT "p"."XId", "p"."IP", "p"."Port", (
    SELECT "t".*
    FROM (
        SELECT "c"."Country"
        FROM "IP2Country" AS "c"
        WHERE "c"."From" <= "p"."IP"
        ORDER BY "c"."From" DESC
        LIMIT 1
    ) AS "t"
    ORDER BY "t"."From" DESC
    LIMIT 1
) AS "Country"
FROM "Xs" AS "p"
07:14:12.7589|[7]|Failed executing DbCommand (59ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT "p"."XId", "p"."IP", "p"."Port", (
    SELECT "t".*
    FROM (
        SELECT "c"."Country"
        FROM "IP2Country" AS "c"
        WHERE "c"."From" <= "p"."IP"
        ORDER BY "c"."From" DESC
        LIMIT 1
    ) AS "t"
    ORDER BY "t"."From" DESC
    LIMIT 1
) AS "Country"
FROM "Xs" AS "p"
07:14:12.8053|[7]|An exception occurred in the database while iterating the results of a query for context type 'XYZ.PostgreSql.PostgreSqlXYZContext'.
Npgsql.PostgresException (0x80004005): 42703: column t.From does not exist
   at Npgsql.NpgsqlConnector.<DoReadMessage>d__155.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()
   at Npgsql.NpgsqlConnector.<ReadMessage>d__154.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Npgsql.NpgsqlConnector.<ReadMessage>d__154.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()
   at Npgsql.NpgsqlConnector.<ReadExpecting>d__161`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()
   at Npgsql.NpgsqlDataReader.<NextResult>d__32.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Npgsql.NpgsqlDataReader.NextResult()
   at Npgsql.NpgsqlCommand.<Execute>d__71.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()
   at Npgsql.NpgsqlCommand.<ExecuteDbDataReader>d__92.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()
   at Npgsql.NpgsqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, DbCommandMethod executeMethod, IReadOnlyDictionary`2 parameterValues)
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteReader(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.BufferlessMoveNext(DbContext _, Boolean buffer)
   at Microsoft.EntityFrameworkCore.Storage.Internal.NpgsqlExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.MoveNext()
   at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext()

@Kirill-Maurin
Copy link
Author

It seems like the first three are implemented in 2.1

"group by"
No logged errors, no logged queries, no data in my application

14:30:47.3502|[1]|Entity Framework Core 2.1.0-preview1-28290 initialized 'PostgreSqlP2PContext' using provider 'Npgsql.EntityFrameworkCore.PostgreSQL' with options: None
14:30:47.6162|[1]|Opening connection to database 'P2P' on server 'tcp://test:1234'.
14:30:48.0547|[13]|Opened connection to database 'P2P' on server 'tcp://test:1234'.
14:30:48.0678|[13]|Beginning transaction with isolation level 'Snapshot'.
14:30:48.2708|[5]|Compiling query model: 
'from IGrouping<<>f__AnonymousType3<string, int>, YDetails> g in 
    (from Z2Ks t2K in DbSet<Z2Ks>
    join Z2P t2P in DbSet<Z2P>
    on new <>f__AnonymousType7<DateTime, int>(
        [t2K].Updated, 
        [t2K].ZId
    ) equals new <>f__AnonymousType7<DateTime, int>(
        [t2P].ZUpdated, 
        [t2P].ZId
    )
    join P p in DbSet<P>
    on new <>f__AnonymousType0<DateTime, string>(
        [t2P].PUpdated, 
        [t2P].PId
    ) equals new <>f__AnonymousType0<DateTime, string>(
        [p].Updated, 
        [p].Id
    )
    join P2X p2T in DbSet<P2X>
    on new <>f__AnonymousType2<DateTime, string>(
        [t2P].PUpdated, 
        [t2P].PId
    ) equals new <>f__AnonymousType2<DateTime, string>(
        [p2T].PUpdated, 
        [p2T].PId
    )
    join X t in DbSet<X>
    on [p2T].XId equals [t].Id
    where [t2K].Outdated == __MaxValue_Date_0 && [p].Outdated == __MaxValue_Date_1 && [p2T].Outdated == __MaxValue_Date_2
    join Y t2P in 
        (from Y <generated>_1 in DbSet<Y>
        select [<generated>_1]).FromSql('select t2p.*, (select i2c."Country" from "IP2Country" i2c where i2c."From" < t2p."IP" order by i2c."From" desc limit 1) from "X2Ys" t2p')
    on [t].Id equals [t2P].XId
    select new YDetails{ 
        ZId = [t2K].ZId, 
        XId = [t].Id, 
        Size = [t].Size ?? 0, 
        IP = [t2P].IP, 
        Port = [t2P].Port, 
        Country = [t2P].Country, 
        Updated = [t2P].Updated 
    }
    ).GroupBy(new <>f__AnonymousType3`2(Country = [t2P].Country, ZId = [t2K].ZId), new YDetails() {ZId = [t2K].ZId, XId = [t].Id, Size = ([t].Size ?? 0), IP = [t2P].IP, Port = [t2P].Port, Country = [t2P].Country, Updated = [t2P].Updated})
from YDetails gg in [g]
select new <>f__AnonymousType4<int, string>(
    [gg].ZId, 
    [gg].Country
)'
14:30:48.3391|[5]|Optimized query model: 
'from IGrouping<<>f__AnonymousType3<string, int>, YDetails> g in 
    (from Z2Ks t2K in DbSet<Z2Ks>
    join Z2P t2P in DbSet<Z2P>
    on new <>f__AnonymousType7<DateTime, int>(
        [t2K].Updated, 
        [t2K].ZId
    ) equals new <>f__AnonymousType7<DateTime, int>(
        [t2P].ZUpdated, 
        [t2P].ZId
    )
    join P p in DbSet<P>
    on new <>f__AnonymousType0<DateTime, string>(
        [t2P].PUpdated, 
        [t2P].PId
    ) equals new <>f__AnonymousType0<DateTime, string>(
        [p].Updated, 
        [p].Id
    )
    join P2X p2T in DbSet<P2X>
    on new <>f__AnonymousType2<DateTime, string>(
        [t2P].PUpdated, 
        [t2P].PId
    ) equals new <>f__AnonymousType2<DateTime, string>(
        [p2T].PUpdated, 
        [p2T].PId
    )
    join X t in DbSet<X>
    on [p2T].XId equals [t].Id
    where [t2K].Outdated == __MaxValue_Date_0 && [p].Outdated == __MaxValue_Date_1 && [p2T].Outdated == __MaxValue_Date_2
    join Y t2P in DbSet<Y>
    on [t].Id equals [t2P].XId
    select new YDetails{ 
        ZId = [t2K].ZId, 
        XId = [t].Id, 
        Size = [t].Size ?? 0, 
        IP = [t2P].IP, 
        Port = [t2P].Port, 
        Country = [t2P].Country, 
        Updated = [t2P].Updated 
    }
    ).GroupBy(new <>f__AnonymousType3`2(Country = [t2P].Country, ZId = [t2K].ZId), new YDetails() {ZId = [t2K].ZId, XId = [t].Id, Size = ([t].Size ?? 0), IP = [t2P].IP, Port = [t2P].Port, Country = [t2P].Country, Updated = [t2P].Updated})
from YDetails gg in [g]
select new <>f__AnonymousType4<int, string>(
    [gg].ZId, 
    [gg].Country
)'
14:30:48.5713|[4]|Disposing transaction.
14:30:48.5713|[4]|Closing connection to database 'P2P' on server 'tcp://test:1234'.
14:30:48.5812|[4]|Closed connection to database 'P2P' on server 'tcp://test:1234'.

@Kirill-Maurin
Copy link
Author

Kirill-Maurin commented Apr 16, 2018

It seems like the first three are implemented in 2.1

Extension for missed "out-the-box" features
This query cannot be generated by EF Core, if type of field "From" is IPAddress.

select i2c."Country" from "IP2Country" i2c where i2c."From" < t2p."IP" order by i2c."From" desc limit 1

A solution with linq2Db

[Sql.Expression( "{0} <= {1}", PreferServerSide = true, IsPredicate = true )]
public static bool LessOrEqual( IPAddress left, IPAddress right ) => left.CompareTo( right ) <= 0;

@Kirill-Maurin
Copy link
Author

#4 requires more than just changing the LINQ provider.

  1. LINQ is not limited to SELECT queries
  2. linq2db can do bulk operations for many DBMS, if you have a mapping scheme
  3. Mapping scheme can be generated from EF Core data model

@ErikEJ
Copy link
Contributor

ErikEJ commented Apr 16, 2018

@Kirill-Maurin have you tried preview-2 ?

@roji
Copy link
Member

roji commented Apr 16, 2018

@Kirill-Maurin i can't answer for the rest, but special PostgreSQL types (e.g. inet) are already fully supported by the Npgsql provider, and AFAIK operators on them should be translated to SQL as well. If you're seeing a problem please open an issue on Npgsql.EntityFrameworkCore.PostgreSQL with the C# code you're trying out (that's missing above)

@Kirill-Maurin
Copy link
Author

Kirill-Maurin commented Apr 16, 2018

@roji
Thanks, Npgsql provider works well

@ErikEJ
Thanks, preview-2 works better than preview-1 (nested queries)

10:52:10.4781|[1]|Entity Framework Core 2.1.0-preview2-30571 initialized 'PostgreSqlXYZContext' using provider 'Npgsql.EntityFrameworkCore.PostgreSQL' with options: None
10:52:10.5978|[1]|Opening connection to database 'XYZ' on server 'tcp://test:1234'.
10:52:11.5554|[12]|Opened connection to database 'XYZ' on server 'tcp://test:1234'.
10:52:11.5554|[12]|Beginning transaction with isolation level 'ReadCommitted'.
10:52:11.7766|[9]|Compiling query model: 
'from X2Y p in DbSet<X2Y>
select new <>f__AnonymousType3<BigInteger, string>(
    [p].IP, 

        (from IP2Country c in DbSet<IP2Country>
        where [c].From <= [p].IP
        order by [c].From asc
        select [c]).FirstOrDefault().Country
)'
10:52:11.8408|[9]|Optimized query model: 
'from X2Y p in DbSet<X2Y>
select new <>f__AnonymousType3<BigInteger, string>(
    [p].IP, 

        (from IP2Country c in DbSet<IP2Country>
        where [c].From <= [p].IP
        order by [c].From asc
        select [c].Country).FirstOrDefault()
)'
10:52:12.0420|[9]|(QueryContext queryContext) => IEnumerable<<>f__AnonymousType3<BigInteger, string>> _InterceptExceptions(
    source: IEnumerable<<>f__AnonymousType3<BigInteger, string>> _ShapedQuery(
        queryContext: queryContext, 
        shaperCommandContext: SelectExpression: 
            SELECT p."IP", (
                SELECT c."Country"
                FROM "IP2Country" AS c
                WHERE c."From" <= p."IP"
                ORDER BY c."From"
                LIMIT 1
            ) AS "Country"
            FROM "X2Ys" AS p, 
        shaper: TypedProjectionShaper<ValueBufferShaper, ValueBuffer, <>f__AnonymousType3<BigInteger, string>>), 
    contextType: XYZ.PostgreSql.PostgreSqlXYZContext, 
    logger: DiagnosticsLogger<Query>, 
    queryContext: queryContext)
10:52:12.0750|[9]|Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT p."IP", (
    SELECT c."Country"
    FROM "IP2Country" AS c
    WHERE c."From" <= p."IP"
    ORDER BY c."From"
    LIMIT 1
) AS "Country"
FROM "X2Ys" AS p
10:52:12.1803|[9]|Executed DbCommand (106ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT p."IP", (
    SELECT c."Country"
    FROM "IP2Country" AS c
    WHERE c."From" <= p."IP"
    ORDER BY c."From"
    LIMIT 1
) AS "Country"
FROM "X2Ys" AS p

@Kirill-Maurin
Copy link
Author

Unfortunately, for my case of "group by" review-2 works no better than review-1
No DbCommands and queries in my log, no data in my application

@Kirill-Maurin
Copy link
Author

EF Core 2.1 preview2 cannot create migration

System.TypeLoadException: Could not load type 'Microsoft.EntityFrameworkCore.Storage.IRelationalCoreTypeMapper' from assembly 'Microsoft.EntityFrameworkCore.Relational, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.
   at Microsoft.Extensions.DependencyInjection.NpgsqlEntityFrameworkServicesBuilderExtensions.AddEntityFrameworkNpgsql(IServiceCollection serviceCollection)
   at Microsoft.EntityFrameworkCore.Infrastructure.Internal.NpgsqlOptionsExtension.ApplyServices(IServiceCollection services)
   at Microsoft.EntityFrameworkCore.Internal.ServiceProviderCache.ApplyServices(IDbContextOptions options, ServiceCollection services)
   at Microsoft.EntityFrameworkCore.Internal.ServiceProviderCache.<>c__DisplayClass4_0.<GetOrAdd>b__2(Int64 k)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
   at Microsoft.EntityFrameworkCore.Internal.InternalAccessorExtensions.GetService[TService](IInfrastructure`1 accessor)
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func`1 factory)
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Could not load type 'Microsoft.EntityFrameworkCore.Storage.IRelationalCoreTypeMapper' from assembly 'Microsoft.EntityFrameworkCore.Relational, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.

@smitpatel
Copy link
Contributor

Nested query bug posted above. Duplicate of #11326 Fixed in 2.1.0-preview2

@smitpatel
Copy link
Contributor

GroupBy issue seems like you are generating query and enumerator but you are not iterating it. If you are not consuming group, we don't do the work to retrieve data. Given that there are customers out there using GroupBy successfully, it seems like something is amiss in user code which is causing no sql to be seen in the logs.

@Kirill-Maurin
Copy link
Author

Kirill-Maurin commented Apr 17, 2018

@smitpatel

Nested query bug posted above. Duplicate of #11326 Fixed in 2.1.0-preview2

Thanks

GroupBy issue seems like you are generating query and enumerator but you are not iterating it.

I use the same code to reproduce. I change only query and/or LINQ-provider.
linq2db works fine

12:26:09.5150|[1]|Entity Framework Core 2.1.0-preview2-30571 initialized 'PostgreSqlXYZContext' using provider 'Npgsql.EntityFrameworkCore.PostgreSQL' with options: None
12:26:09.6222|[1]|Opening connection to database 'XYZ' on server 'tcp://test:1234'.
12:26:10.4541|[12]|Opened connection to database 'XYZ' on server 'tcp://test:1234'.
12:26:10.4541|[12]|Beginning transaction with isolation level 'Snapshot'.
12:26:10.6298|[6]|Expression test code generated: 'E:\Temp\linq2db\ExpressionTest.0.cs'. DataConnection
12:26:11.6415|[6]|--  PostgreSQL.9.2 PostgreSQL
DECLARE @p1 Timestamp -- DateTime
SET     @p1 = '2018-04-16'
DECLARE @p2 Timestamp -- DateTime
SET     @p2 = '9999-12-31'
DECLARE @p3 Timestamp -- DateTime
SET     @p3 = '9999-12-31'
DECLARE @p4 Timestamp -- DateTime
SET     @p4 = '9999-12-31'

SELECT
	t3."Code",
	t3."Name",
	g1.c11 as c111,
	g1.c2 as c21,
	g1.c3 as c31,
	g1.c4 as c41
FROM
	(
		SELECT
			"t2K"."ZId",
			"t2P1".c1 as c11,
			Sum(Coalesce(t."Size", 0)) as c2,
			COUNT(DISTINCT t."Id") as c3,
			COUNT(DISTINCT (Cast("t2P1"."IP" as VarChar(100)) || ':' || Cast("t2P1"."Port" as VarChar(11)))) as c4
		FROM
			"Z2Keywords" "t2K"
				INNER JOIN "Z2P" "t2P" ON "t2K"."Updated" = "t2P"."ZUpdated" AND "t2K"."ZId" = "t2P"."ZId"
				INNER JOIN "P" p ON "t2P"."PUpdated" = p."Updated" AND ("t2P"."PId" IS NULL AND p."Id" IS NULL OR "t2P"."PId" = p."Id")
				INNER JOIN "P2Xs" "p2T" ON "t2P"."PUpdated" = "p2T"."PUpdated" AND ("t2P"."PId" IS NULL AND "p2T"."PId" IS NULL OR "t2P"."PId" = "p2T"."PId")
				INNER JOIN "Xs" t ON "p2T"."XId" IS NULL AND t."Id" IS NULL OR "p2T"."XId" = t."Id"
				INNER JOIN (
					SELECT
						t2."XId",
						t2."Updated",
						(
							SELECT
								t1."Country"
							FROM
								"IP2Country" t1
							WHERE
								t1."From" <= t2."IP"
							ORDER BY
								t1."From" DESC
							LIMIT 1
						) as c1,
						t2."IP",
						t2."Port"
					FROM
						"X2Ys" t2
				) "t2P1" ON t."Id" IS NULL AND "t2P1"."XId" IS NULL OR t."Id" = "t2P1"."XId"
		WHERE
			"t2P1"."Updated" = :p1 AND
			"p2T"."Outdated" = :p2 AND
			p."Outdated" = :p3 AND
			"t2K"."Outdated" = :p4
		GROUP BY
			"t2K"."ZId",
			"t2P1".c1
	) g1
		INNER JOIN "Zs" t3 ON g1."ZId" = t3."Id"
 DataConnection
12:26:11.9834|[6]|Query Execution Time: 00:00:00.3384215
 DataConnection
12:26:12.0770|[11]|Total Execution Time: 00:00:00.6172998. Rows Count: 545.
 DataConnection

@smitpatel
Copy link
Contributor

I use the same code to reproduce. I change only query and/or LINQ-provider.
linq2db works fine

Does EF Core gives you incorrect results? Or shows you empty results when there are results? Did you verify results by EF Core? If you see that there are no results generated when you verify them, please file a new issue with detailed repro steps. (ideally a repro solution)

EF Core using streaming for results. It will create the query and do all groundwork but reading actual data for server or running SQL queries (especially in the case where there are more than 1 SQL to be run), will depend on consumption of results from client code. If you are not consuming the results of the query, EF Core will not generate client objects for result. This is pattern allows you to iterate over a large result set without running out of memory because you can keep only data in memory which is needed for current iteration. Not all ORM or linq to sql translator work this way and they may be computing results even without getting enumerated. Difference in such behaviour is not indication that EF core is not working.

@smitpatel
Copy link
Contributor

Verified that if you call GetEnumerator on query but do not enumerate the results, EF Core will not execute any SQL on server.

@MaceWindu
Copy link

You asked for it...
https://github.com/linq2db/linq2db.EntityFrameworkCore

@Kirill-Maurin
Copy link
Author

@MaceWindu
Excellent!
I do not even know when I myself would have time

@MaceWindu
Copy link

@nathan-parkinson
Copy link

@MaceWindu This is awesome. Please please continue to develop and maintain this project. With entityframework core and linq2db effectively combined there is a full feature set. This would be a very powerful ORM setup.

Is there a roadmap for this project?

@MaceWindu
Copy link

@nathan-parkinson not sure what we can include into roadmap. It is pretty much feature-complete project. I think next week we can release it on nuget taking into account EF.Core 2.1 release.

@nathan-parkinson
Copy link

@MaceWindu Sorry, I think I'm asking the wrong question. I suppose what i'm trying to ask is whether it is a safe option to add this into my projects. Will this be maintained and released - currently the readme states it is in early preview - or is this an experimental repo that could be discontinued at any time.

@MaceWindu
Copy link

@nathan-parkinson it is in preview, because we didn't get any feedback yet from real users. We don't plan to drop this project and if it will get enought attention from users, we will consider to include it into linq2db directly later.

@nathan-parkinson
Copy link

@MaceWindu Thanks for the information. If I have any useful feedback I will let you know

@divega
Copy link
Contributor

divega commented Jun 3, 2018

@MaceWindu thanks for the information on the missing extension points. Could you please create one or two new issues for these so that we can discuss them in triage?

@aspnet-hello
Copy link

We periodically close 'discussion' issues that have not been updated in a long period of time.

We apologize if this causes any inconvenience. We ask that if you are still encountering an issue, please log a new issue with updated information and we will investigate.

@aspnet-hello aspnet-hello removed this from the Discussions milestone Sep 24, 2018
@dotnet dotnet locked and limited conversation to collaborators Sep 24, 2018
@ajcvickers ajcvickers added the closed-no-further-action The issue is closed and no further action is planned. label Oct 11, 2019
@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
closed-no-further-action The issue is closed and no further action is planned.
Projects
None yet
Development

No branches or pull requests

9 participants