-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
String based Include #3921
Comments
I just asked the same question here too http://stackoverflow.com/q/34124501/5647927 |
I too would like this, It helps with creating dynamic repositories. I have tried to make a workaround but it seems impossible to return |
I also need this functionality. And I'm not sure if this will be picked up along with this enhancement, but I'm also missing that you can't do a dynamic DbSet: |
This should be a joke. Before C# 6 we didn't have Now that there is |
Marking for re-triage. We should consider this for 1.1 |
In triage we discussed a that using
public Blog GetById(int id, Func<IQueryable<Blog>, IQueryable<Blog>> includeAction)
{
return includeAction(_context.Blogs).Single(b => b.BlogId == id);
} var blog = repository.GetById(
1,
q => q.Include(b => b.Posts).ThenInclude(p => p.Author)
.Include(b => b.Owner)); We also talked about the idea of having a custom data structure that the includes are specified in, which is then translated to the EF methods. This gets super messy with generic methods, see the workaround code I've added to the description of this issue, which translates from strings to the After playing around with this, I am more convinced that a string based API is a really good addition and not just an easy option because it's what we had in EF6. Though one improvement over EF6 would be to allow the hierarchical navigation names to be specified as |
I've added some workaround code to the description of this issue (top of the page) that adds a string-based include method to EF Core. If you're going to use it in a production app, you probably want to look at more caching etc. as it makes extensive use of |
Worth mentioning using this feature is risky if the include string is an unvalidated input coming from a user. |
While recognizing that Core means the team is moving in a different direction, it seems a lot of code we we got used to writing has to be re-learned, and a lot of our old code base is useless now. Your extension code is fine as an answer, but now requires a complete re-write of everything that calls my repository. Not only that, but at least we were able to have lambda includes that gave us intellisense. Now we have to use dot notation in a string which has no intellisense. This seems very backwards and a downgrade from EF6. I know the original request was for a string as a dynamic include, but lambda includes seems germane to the topic. |
I needed to use the string based workaround for a generic method. After implementing it, it kept throwing the "$"'{navigationName}' is not a valid property of '{currentType}'"" exception. Apparently, it was triggered because of the way I declared the collection directly with the interface.
This resulted in a change in the workaround method. Because of the direct declaration of the models it the old solution only detected the IEnumerable interface and not the ICollection interface
|
I found another solutions. I pass Func to Include: |
The problem really is not about "string includes" but about impossibility to create the function that can "dynamically" generate includes from its own parameters, and that means create simple abstract interface functions. Yes, it could be C# problem not EFCore team... but if the only one way to provide highly important practically (e.g. to migrate EF6 IRepository pattern realisation) and theoretically uncurryng operation on your lambdas chain, is do the step back from "strongly typed" to "dynamically typed" in this case, please be brave enough to do this step. P.S. People do not use EF6 |
@rpokrovskij Maybe you are better off with Mongo or other NoSQL Databases? |
@gdoron one function that hides some C# limitations (the impossibility to have simple enough uncurred function to setup includes) do not make EF "not strongly typed"... Of course you can push users to use reflections but that shows only that you just do not understand that interface should be complete (there should be the way to unchain/uncurry "EFCore" includes to one call, because, if you are going to more abstraction, "to set up includes" is one operation). Also I'm sure that it is possible to provide uncurred strongly typed function the way as oxozle promote (of course hiding DbSet). |
@eqbalsajadi String-based include was shipped in EF Core 1.1. That stackoverflow is out-of-date. |
@ajcvickers Thank you |
@ajcvickers I don't get how the string support solves the issue of including multi-level include. When we used to write something like this where my service was in charge to then handling the include: Task<Order> GetOrderByIdAsync(string orderId, params Expression<Func<Order, object>>[] includeProperties);
...
await m_OrdersService.GetOrderByIdAsync(orderId, o => o.Lines.Select(l => l.Releases)); Is this the new way to go to keep my service in charge of handling the include? Task<Order> GetOrderByIdAsync(string orderId, params string[] includePaths);
...
await m_OrdersService.GetOrderByIdAsync(orderId, $"{nameof(Order.Lines)}.{nameof(OrderLine.Releases)}") In that case the include string can break if someone decide to refactor the entities without noticing the issue! |
@ggirard07 Because you can write any API pattern you want, including the one for EF6, and then convert (e.g. parse the lambda expression) to a simple list of concatenated strings before passing to EF. |
@ajcvickers Thanks for the information. EF6 was way more user friendly on this by avoiding any required knowledge about Expression. |
In the older version of EF you were able to do something like, which is useful for dynamic scenarios.
Edited July-18 by @rowanmiller
Workaround
Here is some code that adds two string based overloads of
Include
.context.Blogs.Include("Posts")
andcontext.Blogs.Include("Posts.Author.Photo")
.nameof
feature when including multiple levelscontext.Blogs.Include(nameof(Post.Blog), nameof(Blog.Owner), nameof(Person.Photo))
The text was updated successfully, but these errors were encountered: