Efcore: Query: AsNoTracking/AsTracking methods on Non-EF Queryable providers throws InvalidOperationException

Created on 20 Mar 2017  路  6Comments  路  Source: dotnet/efcore

We've created an abstraction on top of EF that will be our main data access. When we try to moq it in order to retrieve test data to test business logic, this exception is thrown when returning a list as queryable.

System.InvalidOperationException聽: 'There is no method 'AsNoTracking' on type 'Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions' that matches the specified arguments'

Note that it doesn't throw any exception in EF6 (same code with EF6 just works well)
Note also that .Include() doesn't throw anything

Steps to reproduce

Here's code to reproduce the issue

```c#
class Program
{

    static void Main(string[] args)
    {
        var data = new List<EntityTest>
        {
            new EntityTest{ Id=1, Value = "value1"},
            new EntityTest { Id = 1, Value = "value2" },
            new EntityTest { Id = 1, Value = "value3" }
        };
        var repoMoq = new Mock<Repository>();
        repoMoq.Setup(r => r.Get()).Returns(data.AsQueryable());

        var b = new Business(repoMoq.Object);

        Console.WriteLine(string.Join(",", b.GetAll().Select(u => u.Value)));

        Console.ReadKey();
    }
}

public class Business
{
    Repository _repo;

    public Business(Repository repo)
    {
        _repo = repo;
    }

    public IEnumerable<EntityTest> GetAll()
        => _repo.Get()
        .AsNoTracking() // Explodes here
        .ToList();
}

public interface Repository
{
    IQueryable<EntityTest> Get();
}

public class EntityTest
{
    public int Id { get; set; }
    public string Value { get; set; }
}

```

Further technical details

EF Core version: 1.1.1
Database Provider: (e.g. Microsoft.EntityFrameworkCore.SqlServer)
Operating system: Winodws 10
IDE: VS 2017 RTW

closed-fixed type-bug

Most helpful comment

@bassebaba sure. Basically, I did the same thing that the other IQueryable extensions did in a custom IQueryable extension.

  public static class QueryableExtensions
  {
    public static IQueryable<T> AsGatedNoTracking<T>(this IQueryable<T> source) where T : class
    {
      if (source.Provider is EntityQueryProvider)
        return source.AsNoTracking<T>();
      return source;
    }
  }

To use this, you change
myquery.AsNoTracking()
To
myquery.AsGatedNoTracking()

-- Daniel

All 6 comments

@smitpatel to investigate, checking with @anpete who did some related changes in this area previously.

I came across this same issue today and ended up writing my own gated version of AsNoTracking() as a workaround.

Looks like Include/ThenInclude has the special handling, but AsNoTracking does not. Changing from "investigate" to bug. We should also make sure that there aren't other extension methods that need similar changes. (AsTracking is the obvious one. 馃槃)

@cdwaddell Would you be willing to share your workaround?

@bassebaba sure. Basically, I did the same thing that the other IQueryable extensions did in a custom IQueryable extension.

  public static class QueryableExtensions
  {
    public static IQueryable<T> AsGatedNoTracking<T>(this IQueryable<T> source) where T : class
    {
      if (source.Provider is EntityQueryProvider)
        return source.AsNoTracking<T>();
      return source;
    }
  }

To use this, you change
myquery.AsNoTracking()
To
myquery.AsGatedNoTracking()

-- Daniel

Was this page helpful?
0 / 5 - 0 ratings