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

RevEng: Support Views #1679

Closed
Tracked by #827
lajones opened this issue Feb 20, 2015 · 66 comments
Closed
Tracked by #827

RevEng: Support Views #1679

lajones opened this issue Feb 20, 2015 · 66 comments
Assignees
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. providers-beware punted-for-2.2 type-enhancement
Milestone

Comments

@lajones
Copy link
Contributor

lajones commented Feb 20, 2015

Note: This issue is tracking a specific aspect of using EF Core with database views. See #827 for an overview of the areas where EF Core interacts with database views. The completion of this feature does not mean that every aspect of database view support has been implemented.


See also #5719, which is about support for tables without keys.

Part of #830. At the moment we generate code only from tables, not views. Need to include views but may have to consider what we want to use as the primary key.

@roji
Copy link
Member

roji commented May 27, 2016

Just a note for whenever this gets tackled - PostgreSQL views are updatable in some cases, see the docs for when this is valid. I'm not sure if this kind of thing is supported in other databases, just want to make sure views in EFCore aren't approached as necessarily read-only entities.

@ghost
Copy link

ghost commented Jul 10, 2017

any chance that view mapping (which would also require stored proc mapping for insert/update/delete) could be a 2.x feature, or are we likely to have to wait for a 3.0 release?

@divega
Copy link
Contributor

divega commented Jul 11, 2017

@garethsuarez the straightforward answer is that we don't know yet. We haven't even completed the planning for the next version after 2.0. We will take into account votes as well our best effort to understand the usefulness and the cost of each feature.

@tdjastrzebski
Copy link

tdjastrzebski commented Sep 19, 2017

Views can be updatable but the framework will never be able to 100% correctly guess the pk.
Hence, it may make more sense to generate (scaffold) views as regular entities; read-only until pk is defined. Does not it sound like a reasonable deal? Why a separate ViewType? Just to indicate it is read-only while with PK added it may not be? Keep it simple. Not to mention that sql server views (tables too) really do not require pk to be updatable but ok, it is not a good practice.

@roji
Copy link
Member

roji commented Sep 21, 2017

@tdjastrzebski the framework may not need to "guess" the PK - this information might be available in from the database itself, at least in some cases. I admit I'm not sure exactly what is possible and what PK information is exposed by PostgreSQL, but it's important to keep an open mind here with regards to what different databases support (rather than limiting things upfront).

When the times comes to spec this feature out I'd be happy to investigate PostgreSQL capabilities more.

@tdjastrzebski
Copy link

tdjastrzebski commented Sep 21, 2017

@roji I absolutely agree and that was my point. The framework, depending on the provider, may or may not be able to guess the PK. Even more, in some cases (providers) the difference between a view and a table may be blurry or simply table/view concept may not exist at all.

Therefore, I strongly advocate for implementing no special treatment for views.

It is an Entity Framework, not just (some) SQL Entity framework. Why not to simply retrieve views like tables but as read-only with no PK, until PK is manually defined.
In my developer life I have came across several data access frameworks, most of them overly complicated with that respect. Keep it simple please.

@ErikEJ
Copy link
Contributor

ErikEJ commented Sep 21, 2017

@tdjastrzebski
no special treatment for views != Why not to simply retrieve views like tables but read-only with no PK, until PK is manually defined.

@roji
Copy link
Member

roji commented Sep 21, 2017

I must say I tend to agree that technically the table/view distinction isn't necessary interesting or important. However, we should keep in mind that views are a standard relational database concept, so for users to understand and quickly use EF Core we should probably retain the terminology.

In other words, documentation and possibly some API sugar should probably contain "view", even if behind the scene it's just a table without a primary key (and which is therefore also read-only).

@tdjastrzebski
Copy link

tdjastrzebski commented Sep 21, 2017

@roji Again, I could not agree more. Documentation should use commonly understood terms.
However, I would be careful not to (over) design EF Core mainly towards (some) SQL server in mind.
Even for MS SQL Server views supporting "instead of" triggers the table/view distinction from practical perspective does not make much sense.

@ErikEJ: I am unclear about what you mean by this predicate. In my opinion views support could be simply enabled with "as-is" 2.0 functionality. Albeit I must admit, I have not followed EF Core development closely and I am not aware of all the constraints/dependencies so I could be wrong.
What I know, however, is that by 'fooling' EF Core to generate entities for my views (see #9854 for details) I get just what I need.

@tdjastrzebski
Copy link

tdjastrzebski commented Sep 21, 2017

And just a thought: if you really need to distinguish tables and views do so using marker interface only - the harmless way.

@bricelam
Copy link
Contributor

@tdjastrzebski ViewType is just a fancy word we've been using to describe read-only entity types without a key. At the API level, they'll probably end up looking just like any other entity type.

@bricelam
Copy link
Contributor

I imagine RevEng will generate a normal entity type with an additional configuration like .IsReadOnly() and no .HasKey() call.

@tdjastrzebski
Copy link

tdjastrzebski commented Sep 25, 2017

@bricelam Thank you for the explanation. I think ReadOnlyDbSet<T> may be another option.

@bricelam
Copy link
Contributor

bricelam commented Sep 25, 2017

Oh I like that--it could hide .Add() and .Remove(). I'm sure @divega and @anpete have also considered it, but I'll cc them just in case.

@anpete
Copy link
Contributor

anpete commented Sep 25, 2017

Yep, working name is DbView<T> 😄

@roji
Copy link
Member

roji commented May 4, 2019

It's also worth pointing out that EF Core does distinguish between general-purpose data access, to non-relational data stores (e.g. in-memory provider, CosmosDB provider), and specific support for relational databases (SQL). All support for the latter can be found in Microsoft.EntityFrameworkCore.Relational, which is also published as a separate nuget. For example, all components generating SQL are part of relational (and it can definitely be said that SQL is a database-specific concept).

So within the specific support for relational databases, relational-specific concepts do seem to make sense. However, the non-relational parts of EF Core are "unpolluted" by these in any way.

@tdjastrzebski
Copy link

tdjastrzebski commented May 5, 2019

@roji, @ajcvickers My point is in modern relational databases functional distinction between tables and views is blurry. Hence, such distinction does not make sense in a framework aimed at providing abstraction layer. What makes sense instead are read-write and read-only entity sets.
It has nothing to do with indexes or any other objects needed mostly 'under the hood' to build queries and optimize performance. Perhaps direct DB object mapping helps code-first but let's be honest, code-first is and always will be best suited for simple demos.

@divega
Copy link
Contributor

divega commented May 6, 2019

@tdjastrzebski I really appreciate your feedback. It seems you and I agree on a few points, although not on all 😄

but let's be honest, code-first is and always will be best suited for simple demos.

I am going to assume for now that this isn’t true, that EF and EF Core are very popular O/RMs successfully used by a large number of .NET developers, and that many of those customers are successfully using the code first approach, because this is more in line with data I have.

Tables and views are database concepts. Distinction between those two, IMHO, does not make sense in EF.

I think it is fair to say that EF Core tries to abstract common aspects of databases to enable customers to write code that queries and persists data in terms of entities, typically using a DbContext.
This abstraction is achieved with help from two-way mappings between database objects and entities, which are associated with a DbContext. I think it is natural and expected that the APIs that are used (typically in code that is part of the DbContext) to define those mappings often refer to database concepts.

My point is in modern relational databases functional distinction between tables and views is blurry.

I think it is true that at the database level tables and views can be used pretty much interchangeably (views may be more often read-only or have no keys, but we know that is not universally true, and I think we are all mostly in agreement that conflating these concepts was a bad idea).

The actual difference between tables and views is in how they are defined: while tables represent named storage areas with a specific schema, views are named virtual tables based on queries over other tables or views.

In alignment with all of this, our plan for EF Core 3.0 is that entities configured to map to views will have the exact same query and persistence capabilities as entities mapped to tables. The only difference between ToView and ToTable will be in what migrations and EnsureCreated will do with them:

  • If you use ToTable, a table will be created

  • If you use ToView, a table will not be created.

Ideally EF Core migrations and EnsureCreated should have the capability to create views instead, but for now that is not the case. We are missing migrations operations that represent DDL for views, and an API to associate a defining query with the view. Given this limitation, migrations and EnsureCreated will have to simply ignore (not try to create any DDL) for any database object introduced to the model with ToView.

And this is where I have my actual concerns with ToView:

If someday we want to add the capability to create database views, an argument providing a defining query for the view would be required, but is it ok to just implicitly ignore the object if it isn’t provided?

I think the connection between the ToView method and the behavior (database object is to be ignored by migrations and EnsureCreated) becomes too implicit and obscure. E.g.:

  • The behavior isn't conveyed at all by the name of the API, so it is not discoverable.

  • Once customers learn how it works, they could start calling ToView for tables in the database for which they don’t want EF Core to ever produce any DDL.

That might work, but would it really be ok? It reminds me of the kind of thing that happens when we make it too easy to conflate orthogonal concepts, e.g. when customers started trying to use the Query<T> API with tables that they wanted to treat as read-only, even if they had primary keys defined.

ErikEJ added a commit to ErikEJ/EntityFramework that referenced this issue May 7, 2019
smitpatel pushed a commit that referenced this issue May 7, 2019
@smitpatel
Copy link
Member

Note: Verify generated file content and E2E experience and close the issue.

@ErikEJ
Copy link
Contributor

ErikEJ commented May 8, 2019

Thanks, @smitpatel, I will also try to verify manually from the daily build.

@bricelam
Copy link
Contributor

bricelam commented May 9, 2019

@smitpatel @ErikEJ Can this be closed?

@bricelam bricelam added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label May 10, 2019
@ajcvickers ajcvickers modified the milestones: 3.0.0, 3.0.0-preview6 Jun 5, 2019
@ErikEJ
Copy link
Contributor

ErikEJ commented Jun 15, 2019

@smitpatel @bricelam Confirmed that this works as desired with preview6 and AdventureWorks2014:

        modelBuilder.Entity<VVendorWithContacts>(entity =>
        {
            entity.HasNoKey();

            entity.ToTable("vVendorWithContacts", "Purchasing");

@abrantie1z
Copy link

Kudus EF Core Team. Much Love from Ghana! We appreciate your efforts.

@abrantie1z
Copy link

abrantie1z commented Jul 16, 2019

However there are errors:
Screenshot (23)
i scaffolded a single view using reverse engineering which worked like charm. i went through the DBContext class and it had the HasNoKey() method. but when i try to get records front the view, i get this error.

the codes i wrote to get the records from the view is:
Screenshot (24)

@ajcvickers
Copy link
Member

ajcvickers commented Jul 16, 2019

@garethsuarez @abrantie1z What version of EF Core are you using?

@abrantie1z
Copy link

@ajcvickers I am using Microsoft.EntityFrameworkCore.Tools 3.0.0-preview6.19304.10

@ErikEJ
Copy link
Contributor

ErikEJ commented Jul 17, 2019

@abrantie1z Preview 6 is buggy... Wait for preview 7

@danobri
Copy link

danobri commented May 20, 2020

Is there a way to continue to only scaffold tables in EF Core 3.0? I don't see a switch to enable / disable view scaffolding in the documentation.

@ErikEJ
Copy link
Contributor

ErikEJ commented May 20, 2020

@danobri No, currently you must specify the tables to scaffold on the command line, our use a tool like EF Core Power Tools, that makes this simpler for you.

@danobri
Copy link

danobri commented May 20, 2020

Thanks for confirming. Would be great to have a switch on Scaffold-DbContext to opt in or out of view scaffolding. This is essentially a breaking change for our project, as we have been doing database first with Scaffold-DbContext -force since EF Core v1, and handling views manually given the lack of support for them.

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. providers-beware punted-for-2.2 type-enhancement
Projects
None yet
Development

No branches or pull requests