question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Move IQueryableExtensions to Microsoft.Data.Entity namespace

See original GitHub issue

Currently, the Async extension methods, like CountAsync() and ToListAsync() live in the System.Linq namespace. However, most methods depend on IAsyncQueryProvider to work, which is specific to Entity Framework.

The problem here is, that if someone else writes a LINQ provider with a CountAsync() extension method with no dependency on Entity Framework, this setup cannot work anymore if you combine the two in one project. The only ways to prevent compile time problems, is one of the following awful options:

  1. Remove the System.Linq namespace reference; but this then breaks all LINQ queries (using Where, Select, etc.), including query comprehension syntax. So that’s not an option.
  2. Rewrite all async methods over non-EF queries to to explicit Class.MethodAsync(query, ...) syntax rather than query.MethodAsync(...). (And if the other library was just as smart as EF, rewrite your EF queries too!)

Please, please, don’t assume you’re the only LINQ provider out there. Pick your own extension namespace (such as Microsoft.Data.Entity), or play nicer with other async IQueryProviders. Right now, there’s no way to opt-out.

Issue Analytics

  • State:closed
  • Created 9 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
rubenprinscommented, Mar 11, 2015

@rowanmiller, please don’t just close this issue off without considering you might be wrong. Because you are very wrong.

We’ve had the methods in this namespace for a number of releases now and there hasn’t been an issue.

The current EF does not pollute the System.Linq namespace: all queryable extension methods are defined in System.Data.Entity.QueryableExtensions. This means I can opt-out of them. So this co-opting of System.Linq is a change to the public facing side of EF. It is an entirely new issue.

And I predict: in the future, when you do realise you’ve broken many scenarios, the argument will probably be “we can’t remove it again, because that would be a breaking change”.

And, by moving QueryableExtensions to System.Linq you are actually breaking existing code, that has nothing to do with EF. At my company we actually do use like-named methods (albeit scoped to our own namespace), such as Include, and quite surprisingly to you perhaps, ToListAsync, CountAsync.

Your co-opting of the namespace System.Linq means that even the mere presence of EntityFramework.dll will require us to rewrite existing code:

var count = (from x in context.Something.Include(x => x.Relation); // <- ambiguous method call
             where x.SomethingElse == whatever
             orderby x.Orderable
             select x).CountAsync(); // <- ambiguous method call

Apart from the obfuscated identifiers, this is actual working code right now in our projects! But if EF7 would be present (directly or even indirectly), we’d have to rewrite all such code to something like

var count = OtherFrameworkExtensions.CountAsync(
             from x in OtherFrameworkExtensions.Include(context.Something, x => x.Relation)
             where x.SomethingElse == whatever
             orderby x.Orderable
             select x);

By co-opting the System.Linq namespace, EF has become viral: it infects all code that uses LINQ, whether you have a hard dependency on EF or an indirect dependency on EF through a referenced project (because the C# compiler chain knows no indirect dependencies).

If it ever becomes an issue it probably just means it’s time to define a common contract for them and share it.

It already is an issue. So please don’t make this decision lightly, before you unleash this breaking change.

However, it doesn’t seem super likely that this will happen with a technology defining the same methods and being used in the same project as EF.

Same solution you mean. Because if any project even indirectly references EntityFramework, the NuGet and C# compiler system promote them to an actual hard depency/reference, and then boom: broken code.

And you have already broken our company’s code, so the problem is indeed super likely. Unless you’re writing simple pet shop or music store toy applications. Think bigger: think actual enterprise code bases, with dozens of libraries/project references.

Also, never heard of other ORMs, like NHibernate? Are they no longer allowed to support async by design? Or are they to beg the EF team to please provide extensibility points within EF just to play nice? Because, like I said: there is no longer a way to opt-out unless you completely remove EF7 from the picture, otherwise you’re likely to run into this issue.

And this is a new issue with EF7. It wasn’t an issue before!

0reactions
HappyNomadcommented, Nov 15, 2016

@rubenprins I also want EF-Core to reference a standard IAsyncQueryProvider. Many of your complaints regarding Ix were resolved, and EF-Core references it anyway, so I think that’s its natural home. In fact, it’s already there although EF-Core still uses its own variation.

My interest in this subject started when I encountered a situation where I need to execute a query in a way that’s independent of EF-Core. I ended up requesting a feature for Ix which I hope to eventually use with EF-Core. That way, like you said, these async query execution methods wouldn’t need to be reinvented by EF-Core or elsewhere.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Move IQueryableExtensions to Microsoft.Data.Entity ...
The problem here is, that if someone else writes a LINQ provider with a CountAsync() extension method with no dependency on Entity Framework, ......
Read more >
Create Data Transfer Objects (DTOs)
Describes how to create data transfer objects (DTOs) manually using code to change the shape of the data sent to the client.
Read more >
System.Data.Entity Namespace
Explore all classes and interfaces of the System.Data.Entity namespace. ... functions for use in DbContext or ObjectContext LINQ to Entities queries.
Read more >
Porting from EF6 to EF Core - Porting a Code-Based Model
Most APIs that you use in EF6 are in the System.Data.Entity namespace (and related sub-namespaces). The first code change is to swap to...
Read more >
Code First Migrations - EF6
Generating migrations to keep track of changes you make to your EF model; Keep your database up to date with those changes. The...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found