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 Find method on DbSet #797

Closed
kirthik opened this Issue Oct 6, 2014 · 28 comments

Comments

@kirthik
Contributor

kirthik commented Oct 6, 2014

In the old world, we have Find method on Dbset that is missing in the new world. It would be nice to have this in new EF world too.

@rowanmiller rowanmiller added this to the Backlog milestone Oct 6, 2014

@bricelam bricelam removed this from the Backlog milestone Mar 16, 2015

@bricelam

This comment has been minimized.

Show comment
Hide comment
@bricelam

bricelam Mar 16, 2015

Member

Note for triage: I'm marking this for re-triage since I'm seeing more and more people asking about this and we haven't done any work on the mitigation we once talked about in the early days of EF7.

Member

bricelam commented Mar 16, 2015

Note for triage: I'm marking this for re-triage since I'm seeing more and more people asking about this and we haven't done any work on the mitigation we once talked about in the early days of EF7.

@jasoncavett

This comment has been minimized.

Show comment
Hide comment
@jasoncavett

jasoncavett Aug 31, 2015

Is FindAsync also in the consideration here as well or is that a separate issue?

jasoncavett commented Aug 31, 2015

Is FindAsync also in the consideration here as well or is that a separate issue?

@divega

This comment has been minimized.

Show comment
Hide comment
@divega

divega Aug 31, 2015

Member

@jasoncavett You can consider FindAsync() part of this issue.

Member

divega commented Aug 31, 2015

@jasoncavett You can consider FindAsync() part of this issue.

@rowanmiller rowanmiller removed this from the Backlog milestone Nov 2, 2015

@rowanmiller

This comment has been minimized.

Show comment
Hide comment
@rowanmiller

rowanmiller Nov 2, 2015

Member

I've seen some good discussion and feedback on this on the ASP.NET Insiders mailing list. We should re-discuss and maybe pull it into RTM.

Member

rowanmiller commented Nov 2, 2015

I've seen some good discussion and feedback on this on the ASP.NET Insiders mailing list. We should re-discuss and maybe pull it into RTM.

@rowanmiller rowanmiller added this to the 7.0.0 milestone Nov 3, 2015

@rowanmiller rowanmiller added the pri0 label Nov 3, 2015

@tidusjar

This comment has been minimized.

Show comment
Hide comment
@tidusjar

tidusjar Nov 24, 2015

I would also like to add that I would like to see FindAsync() and Find() in EF7

tidusjar commented Nov 24, 2015

I would also like to add that I would like to see FindAsync() and Find() in EF7

@sirpadington

This comment has been minimized.

Show comment
Hide comment
@sirpadington

sirpadington Dec 8, 2015

I am also going to add that it would be nice to have Find() in EF7

sirpadington commented Dec 8, 2015

I am also going to add that it would be nice to have Find() in EF7

@bricelam

This comment has been minimized.

Show comment
Hide comment
@bricelam

bricelam Dec 9, 2015

Member

BTW, I have an answer on StackOverflow showing how you could write it yourself.

Member

bricelam commented Dec 9, 2015

BTW, I have an answer on StackOverflow showing how you could write it yourself.

@sirpadington

This comment has been minimized.

Show comment
Hide comment
@sirpadington

sirpadington Dec 9, 2015

That is awesome. I am having a hard time trying to find where IAccessor is located. Any ideas?

sirpadington commented Dec 9, 2015

That is awesome. I am having a hard time trying to find where IAccessor is located. Any ideas?

@bricelam

This comment has been minimized.

Show comment
Hide comment
@bricelam

bricelam Dec 9, 2015

Member

@sirpadington In namespace Microsoft.Data.Entity.Infrastructure.

Member

bricelam commented Dec 9, 2015

@sirpadington In namespace Microsoft.Data.Entity.Infrastructure.

@joeleesh

This comment has been minimized.

Show comment
Hide comment
@joeleesh

joeleesh Feb 3, 2016

@bricelam and @sirpadington do you find reference for IAccessor? I can not find on Microsoft.Data.Entity.Infrastructure?

joeleesh commented Feb 3, 2016

@bricelam and @sirpadington do you find reference for IAccessor? I can not find on Microsoft.Data.Entity.Infrastructure?

@bricelam

This comment has been minimized.

Show comment
Hide comment
@bricelam

bricelam Feb 4, 2016

Member

It was renamed to IInfrastructure<>.

Member

bricelam commented Feb 4, 2016

It was renamed to IInfrastructure<>.

@komengem

This comment has been minimized.

Show comment
Hide comment
@komengem

komengem Apr 10, 2016

What is the progress on this "Add Find method on DbSet #797"?

komengem commented Apr 10, 2016

What is the progress on this "Add Find method on DbSet #797"?

@VSG24

This comment has been minimized.

Show comment
Hide comment
@VSG24

VSG24 Apr 11, 2016

God we need this so much.

VSG24 commented Apr 11, 2016

God we need this so much.

@komengem

This comment has been minimized.

Show comment
Hide comment
@komengem

komengem Apr 17, 2016

Man, i was hoping we would get this in Update 2 👎

komengem commented Apr 17, 2016

Man, i was hoping we would get this in Update 2 👎

@ErikEJ

This comment has been minimized.

Show comment
Hide comment

@rowanmiller rowanmiller modified the milestones: 1.0.1, 1.0.0 May 4, 2016

@sjb-sjb

This comment has been minimized.

Show comment
Hide comment
@sjb-sjb

sjb-sjb Jun 14, 2016

My question about implementing Find in EF7 is the efficiency. It's easy enough to take linear time to loop through the elements and find what you are looking for. But what I expect from Find is that it use the database indices to access the correct element (but without hitting the disk) in some reasonably fast manner like log n or better. If that is not what it does then I want a huge "use at your own risk" or disclaimer about the lack of efficiency in the documentation. Because, the reason I would look to Find in the first place is in the expectation that an in-memory search would be faster than a search to disk.

So, while I obviously appreciate @bricelam's code suggestions on StackOverflow, I wouldn't want the final StackOverflow solution to be the basis of the EF7 implementation (unless that solution does something that I don't know about :-).

sjb-sjb commented Jun 14, 2016

My question about implementing Find in EF7 is the efficiency. It's easy enough to take linear time to loop through the elements and find what you are looking for. But what I expect from Find is that it use the database indices to access the correct element (but without hitting the disk) in some reasonably fast manner like log n or better. If that is not what it does then I want a huge "use at your own risk" or disclaimer about the lack of efficiency in the documentation. Because, the reason I would look to Find in the first place is in the expectation that an in-memory search would be faster than a search to disk.

So, while I obviously appreciate @bricelam's code suggestions on StackOverflow, I wouldn't want the final StackOverflow solution to be the basis of the EF7 implementation (unless that solution does something that I don't know about :-).

ajcvickers added a commit that referenced this issue Jun 16, 2016

Implement DbSet.Find
Issue #797

Semantics are essentially the same as EF6:
- If entity with given key is being tracked, then return it without a database query
- Otherwise, query the database and track and return entity if found
- Otherwise, return null

ajcvickers added a commit that referenced this issue Jun 17, 2016

Implement DbSet.Find
Issue #797

Semantics are essentially the same as EF6:
- If entity with given key is being tracked, then return it without a database query
- Otherwise, query the database and track and return entity if found
- Otherwise, return null

ajcvickers added a commit that referenced this issue Jun 17, 2016

Implement DbSet.Find
Issue #797

Semantics are essentially the same as EF6:
- If entity with given key is being tracked, then return it without a database query
- Otherwise, query the database and track and return entity if found
- Otherwise, return null

@ajcvickers ajcvickers added the 2 - Done label Jun 17, 2016

@ajcvickers ajcvickers closed this Jun 17, 2016

@martinRocks

This comment has been minimized.

Show comment
Hide comment
@martinRocks

martinRocks Jul 1, 2016

If this is done, how do I use it. I have 1.0.0 of EF7 and I don't see the find method.

{
  "version": "1.0.0-*",

  "dependencies": {
    "Domain": "1.0.0-*",
    "Microsoft.EntityFrameworkCore": "1.0.0",
    "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0",
    "Microsoft.EntityFrameworkCore.SqlServer.Design": {
      "version": "1.0.0",
      "type": "build"
    },
    "Microsoft.EntityFrameworkCore.Tools.Core": "1.0.0-rc2-final",
    "NETStandard.Library": "1.6.0"
  },

  "frameworks": {
    "netstandard1.6": {
      "imports": ["dotnet5.6","dnxcore50", "portable-net45+win8"]
    }
  }
}

martinRocks commented Jul 1, 2016

If this is done, how do I use it. I have 1.0.0 of EF7 and I don't see the find method.

{
  "version": "1.0.0-*",

  "dependencies": {
    "Domain": "1.0.0-*",
    "Microsoft.EntityFrameworkCore": "1.0.0",
    "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0",
    "Microsoft.EntityFrameworkCore.SqlServer.Design": {
      "version": "1.0.0",
      "type": "build"
    },
    "Microsoft.EntityFrameworkCore.Tools.Core": "1.0.0-rc2-final",
    "NETStandard.Library": "1.6.0"
  },

  "frameworks": {
    "netstandard1.6": {
      "imports": ["dotnet5.6","dnxcore50", "portable-net45+win8"]
    }
  }
}
@gdoron

This comment has been minimized.

Show comment
Hide comment
@gdoron

gdoron Jul 1, 2016

@martinRocks the milestone is 1.1.0

gdoron commented Jul 1, 2016

@martinRocks the milestone is 1.1.0

@rowanmiller

This comment has been minimized.

Show comment
Hide comment
@rowanmiller

rowanmiller Jul 5, 2016

Member

You can try our nightly feeds, but they are unsupported and only really intended for trying out new features (not building production applications) https://www.myget.org/Gallery/aspnetcidev

Member

rowanmiller commented Jul 5, 2016

You can try our nightly feeds, but they are unsupported and only really intended for trying out new features (not building production applications) https://www.myget.org/Gallery/aspnetcidev

@deepxg

This comment has been minimized.

Show comment
Hide comment
@deepxg

deepxg Sep 2, 2016

Quick question about the intended implementation, because a couple of people have posted the link to 'workarounds' on StackOverflow: will the final version maintain an identity map? Right now if you're in a loop, say, and do SingleOrDefault for the ID, adding the entity if it's not found, you will get duplicate key violations when you submit the changes to the database. Ideally, Find will be smart enough to return the new, unpersisted entity reference, instead of always hitting the database.

deepxg commented Sep 2, 2016

Quick question about the intended implementation, because a couple of people have posted the link to 'workarounds' on StackOverflow: will the final version maintain an identity map? Right now if you're in a loop, say, and do SingleOrDefault for the ID, adding the entity if it's not found, you will get duplicate key violations when you submit the changes to the database. Ideally, Find will be smart enough to return the new, unpersisted entity reference, instead of always hitting the database.

@ajcvickers

This comment has been minimized.

Show comment
Hide comment
@ajcvickers

ajcvickers Sep 2, 2016

Member

Yes, Find uses an identity map. Yes, find will return the new, unpersisted entity.

Member

ajcvickers commented Sep 2, 2016

Yes, Find uses an identity map. Yes, find will return the new, unpersisted entity.

@sjb-sjb

This comment has been minimized.

Show comment
Hide comment
@sjb-sjb

sjb-sjb Mar 28, 2017

I would like to reopen this discussion to ask for a version of Find that only looks in memory, and does not go to the database. The point is to use the EF indices to find the entry quickly, if it is in memory.

My use case is this: I have a variety of views with viewmodels that can reference overlapping data i.e. the same entity loaded through several contexts. I want to be able to switch back and forth between the views and have them all up to date. I have no desire to implement my own identity resolution so that the different views/viewmodels share entities (that they each have loaded using different DbContexts). Neither do I want to reload everything in a given view/viewmodel just because a user edit in some other view/viewmodel has changed one entity. So it seems unavoidable that I will have several copies of a given entity in memory, coming from different DbSets. What I would like to do is, when one of the in-memory entities is changed in one DbSet then I would like to Find the other in-memory copies in the other DbSets (associated with other views / viewmodels) and update them appropriately. Obviously in this situation, having Find hit the database would be counterproductive.

I realize that the philosophy is to dispose the context (and dbSets) after the unit of work is done -- perhaps right after the queries have finished. That doesn't make this problem go away, though. If you drop the context and the dbSets then it just entails that the duplicate entities are no longer associated with dbSets (which makes them even harder to Find :-)

sjb-sjb commented Mar 28, 2017

I would like to reopen this discussion to ask for a version of Find that only looks in memory, and does not go to the database. The point is to use the EF indices to find the entry quickly, if it is in memory.

My use case is this: I have a variety of views with viewmodels that can reference overlapping data i.e. the same entity loaded through several contexts. I want to be able to switch back and forth between the views and have them all up to date. I have no desire to implement my own identity resolution so that the different views/viewmodels share entities (that they each have loaded using different DbContexts). Neither do I want to reload everything in a given view/viewmodel just because a user edit in some other view/viewmodel has changed one entity. So it seems unavoidable that I will have several copies of a given entity in memory, coming from different DbSets. What I would like to do is, when one of the in-memory entities is changed in one DbSet then I would like to Find the other in-memory copies in the other DbSets (associated with other views / viewmodels) and update them appropriately. Obviously in this situation, having Find hit the database would be counterproductive.

I realize that the philosophy is to dispose the context (and dbSets) after the unit of work is done -- perhaps right after the queries have finished. That doesn't make this problem go away, though. If you drop the context and the dbSets then it just entails that the duplicate entities are no longer associated with dbSets (which makes them even harder to Find :-)

@ajcvickers

This comment has been minimized.

Show comment
Hide comment
@ajcvickers
Member

ajcvickers commented Mar 28, 2017

@sjb-sjb Covered by #7391

@sjb-sjb

This comment has been minimized.

Show comment
Hide comment
@sjb-sjb

sjb-sjb Mar 28, 2017

@ajcvickers thanks for this reference.

Do you have any general / high level comment on the overall goal of synchronizing multiple copies of an entity, which arises due to loading the entity multiple times through different contexts? I think this problem is inevitable when you have multiple views of the data, but is it really? I would like to know if I've just gotten lost in the rabbit hole. What is the usual way to deal with this?

All the best
sjb

P.s. If this is in fact a standard problem (inter-context identity resolution would be one way to describe it) then it would be nice to have a standard way of dealing with it.

sjb-sjb commented Mar 28, 2017

@ajcvickers thanks for this reference.

Do you have any general / high level comment on the overall goal of synchronizing multiple copies of an entity, which arises due to loading the entity multiple times through different contexts? I think this problem is inevitable when you have multiple views of the data, but is it really? I would like to know if I've just gotten lost in the rabbit hole. What is the usual way to deal with this?

All the best
sjb

P.s. If this is in fact a standard problem (inter-context identity resolution would be one way to describe it) then it would be nice to have a standard way of dealing with it.

@ajcvickers

This comment has been minimized.

Show comment
Hide comment
@ajcvickers

ajcvickers Mar 28, 2017

Member

@sjb-sjb Keep it constrained. That is, for an arbitrary number of instances, each of which can have any changes to both scalar properties or relationships, and for which there can be new entities, deleted entities, modified entities, and unchanged entities, it is very hard to define what the "correct" behavior is, and hard to come up with rules that will cover all cases. On the other hand, if there are two instances, one is known not to change, and the other only has scalar changes, then the task is pretty easy. So, as much as possible, constraint where and how changes can be made so as to keep your rules for how to merge changes as simple as possible,

Member

ajcvickers commented Mar 28, 2017

@sjb-sjb Keep it constrained. That is, for an arbitrary number of instances, each of which can have any changes to both scalar properties or relationships, and for which there can be new entities, deleted entities, modified entities, and unchanged entities, it is very hard to define what the "correct" behavior is, and hard to come up with rules that will cover all cases. On the other hand, if there are two instances, one is known not to change, and the other only has scalar changes, then the task is pretty easy. So, as much as possible, constraint where and how changes can be made so as to keep your rules for how to merge changes as simple as possible,

@sjb-sjb

This comment has been minimized.

Show comment
Hide comment
@sjb-sjb

sjb-sjb Mar 29, 2017

Thanks for the good advice. I think scalar properties and add / remove are enough. I plan to only change relationships by setting the reference Id, so that's a scalar property. Let's say I add a new child entity and set the parent id. I don't need to also explicitly create the relationship in the traversal collection, do I?

Since the changes are being made on the ui thread and will be immediately propagated to the other entities, there is no way to have conflicting changes in two copies of an entity.

What I realized is that one doesn't want to automatically replicate the changes made in one context in all the other contexts. Creating a relationship between two collections so that one of them picks up changes made in the other, should not be automatic but is an application decision. It should be part of the view model layer.

Obviously MS doesn't have this kind of thing today, for example this goes beyond the intended design of the Template 10 validation / view model system. (ref @JerryNixon) Is there any plan to do something like this in the future? A comprehensive view model system including cross-context synchronization primitives (and validation) would be great.

sjb-sjb commented Mar 29, 2017

Thanks for the good advice. I think scalar properties and add / remove are enough. I plan to only change relationships by setting the reference Id, so that's a scalar property. Let's say I add a new child entity and set the parent id. I don't need to also explicitly create the relationship in the traversal collection, do I?

Since the changes are being made on the ui thread and will be immediately propagated to the other entities, there is no way to have conflicting changes in two copies of an entity.

What I realized is that one doesn't want to automatically replicate the changes made in one context in all the other contexts. Creating a relationship between two collections so that one of them picks up changes made in the other, should not be automatic but is an application decision. It should be part of the view model layer.

Obviously MS doesn't have this kind of thing today, for example this goes beyond the intended design of the Template 10 validation / view model system. (ref @JerryNixon) Is there any plan to do something like this in the future? A comprehensive view model system including cross-context synchronization primitives (and validation) would be great.

@BoubakrEchieb

This comment has been minimized.

Show comment
Hide comment
@BoubakrEchieb

BoubakrEchieb Apr 3, 2017

Microsoft.Data.Entity.Infrastructure namespace is not found !

BoubakrEchieb commented Apr 3, 2017

Microsoft.Data.Entity.Infrastructure namespace is not found !

@sjb-sjb

This comment has been minimized.

Show comment
Hide comment
@sjb-sjb

sjb-sjb Apr 3, 2017

@ajcvickers, a followup on the use of Find in replicating changes from one context to another. My current thinking is to constrain the problem (as you suggest) by only replicating changes when a SaveChanges occurs. That is a lot simpler than the general problem. One can just use Find and/or GetDatabaseValues directly.

sjb-sjb commented Apr 3, 2017

@ajcvickers, a followup on the use of Find in replicating changes from one context to another. My current thinking is to constrain the problem (as you suggest) by only replicating changes when a SaveChanges occurs. That is a lot simpler than the general problem. One can just use Find and/or GetDatabaseValues directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment