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

Add DbSet<T>.Local (or similar) #3915

Closed
joshmouch opened this issue Nov 28, 2015 · 1 comment
Closed

Add DbSet<T>.Local (or similar) #3915

joshmouch opened this issue Nov 28, 2015 · 1 comment
Assignees
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-enhancement
Milestone

Comments

@joshmouch
Copy link

You used to be able to do the following to a DbSet:

context.EntityDbSet.Local.FirstOrDefault(searchLocalQuery)

But it doesn't look like you can anymore (unless I'm missing an extension assembly).

Short of this, a backup is to do the following:

context.ChangeTracker.Entries<YourEntity>().Any(e => e.Entity.Id == id)

However, that only works if you have the context. Is there a way to get the context if you just have a DbSet?

@joshmouch joshmouch changed the title DbSet<T>.Local r how to get context from DbSet<T>? DbSet<T>.Local or else how to get context from DbSet<T>? Nov 28, 2015
@rowanmiller rowanmiller changed the title DbSet<T>.Local or else how to get context from DbSet<T>? Add DbSet<T>.Local (or similar) Dec 2, 2015
@rowanmiller rowanmiller added this to the Backlog milestone Dec 2, 2015
@rowanmiller
Copy link
Contributor

We thought we already had a backlog item to support .Local... but it doesn't look like we do, so turning this into an enhancement to track it.

In the meantime, you can write something like this. It gives you most of what local did, the main difference is that it won't refresh the list if you query for more data. It will sync changes to the list back into the change tracker though.

public static class Extensions
{
    public static ObservableCollection<TEntity> GetLocal<TEntity>(this DbSet<TEntity> set)
        where TEntity : class
    {
        var context = set.GetService<DbContext>();
        var data = context.ChangeTracker.Entries<TEntity>().Select(e => e.Entity);
        var collection = new ObservableCollection<TEntity>(data);

        collection.CollectionChanged += (s, e) =>
        {
            if (e.NewItems != null)
            {
                context.AddRange(e.NewItems.Cast<TEntity>());
            }

            if (e.OldItems != null)
            {
                context.RemoveRange(e.OldItems.Cast<TEntity>());
            }
        };

        return collection;
    }
}

@ajcvickers ajcvickers self-assigned this Jul 8, 2016
ajcvickers added a commit that referenced this issue Aug 24, 2016
Issue #3915

Much of the implementation is the same as for EF6 and most of the tests have been ported directly. Key differences are:
- Calling .Local does not automatically call DetectChanges.
- .Local now returns a custom observable collection type rather than a type derived from ObservableCollection.

Both of these changes were driven by reported perf issues associated with the EF6 .Local. For the first point, DetectChanges can always be slow, and almost always .Local will return the same data regardless of whether DetectChanges is called.

For the second point, creating a new List containing a copy of all the tracked entities could be both slow and use a lot of memory. Also, the use of a list would mean inserts and removes from the list, which could be common, was slow. Therefore, the new type provides a view over the already tracked data without duplicating it.
ajcvickers added a commit that referenced this issue Aug 26, 2016
Issue #3915

Much of the implementation is the same as for EF6 and most of the tests have been ported directly. Key differences are:
- Calling .Local does not automatically call DetectChanges.
- .Local now returns a custom observable collection type rather than a type derived from ObservableCollection.

Both of these changes were driven by reported perf issues associated with the EF6 .Local. For the first point, DetectChanges can always be slow, and almost always .Local will return the same data regardless of whether DetectChanges is called.

For the second point, creating a new List containing a copy of all the tracked entities could be both slow and use a lot of memory. Also, the use of a list would mean inserts and removes from the list, which could be common, was slow. Therefore, the new type provides a view over the already tracked data without duplicating it.
@ajcvickers ajcvickers modified the milestones: 1.1.0, Backlog Aug 26, 2016
@ajcvickers ajcvickers added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Aug 26, 2016
@ajcvickers ajcvickers modified the milestones: 1.1.0-preview1, 1.1.0 Oct 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-enhancement
Projects
None yet
Development

No branches or pull requests

3 participants