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

Reverse engineer support #3

Closed
bricelam opened this issue Nov 21, 2017 · 14 comments
Closed

Reverse engineer support #3

bricelam opened this issue Nov 21, 2017 · 14 comments
Assignees

Comments

@bricelam
Copy link
Member

We'll need to implement IScaffoldingCodeGenerator to support scaffolding a model from the database.

@bricelam bricelam added this to the 2.1.0 milestone Nov 21, 2017
@simon-reynolds
Copy link
Collaborator

Some issues with scaffolding

  • Do we create types as record types or as class types?
  • I think that creating a type per file would not scale well as we would then have to figure out the dependencies between types to ensure they are compiled in the correct order.
    • I would suggest that all types would be scaffolded into one recursive module so they can reference each other without issue

@tylerhartwig
Copy link
Collaborator

Can F# record types be exposed to another C# library? If not I think it would be useful to define the EF Models as class types.

As for the ordering of files, I don't think we have a choice. While it might be bad database design, it is still possible for 2 tables in a database to reference each other, and our model would need to support that. This would required the and keyword, which requires our types are in the same file.

@simon-reynolds
Copy link
Collaborator

Yes, an F# record type is exposed to C# like below

type Person = { Name: string; Age: int }
is exposed as a sealed class with a constructor like
public Person(string name, int age)

F# 4.1 introduced recursive modules so we can declare something like module rec Domain and all the types in it can reference each other without needing the andkeyword

@bricelam
Copy link
Member Author

I think that creating a type per file would not scale well

I'm going to reworking some of the RevEng interfaces for EF Core 2.1, I'll keep in mind that generators may want to put everything into a single file.

@bricelam
Copy link
Member Author

bricelam commented Feb 5, 2018

cc @cartermp (FYI so you can track F# support for this in EF Core)

@bricelam
Copy link
Member Author

bricelam commented Feb 7, 2018

You may use the C# version as a reference implementation. See CSharpModelGenerator and its subcomponents CSharpDbContextGenerator and CSharpEntityTypeGenerator.

@isaacabraham
Copy link
Contributor

Just my two cents. It's been a while since I used EF - if possible, I'd recommend trying to stick with the standard set of types that F# devs use:

  • Records
  • Immutable fields (although I suppose that all the fields on the record will need to be mutable to work with things like change tracking)?
  • If possible, discriminated unions for many-types-per-table style relationships (which would be modelled with inheritance in C#).

@simon-reynolds
Copy link
Collaborator

Depending on interoperability requirements we can create types as either records or class types, maybe depending on an input parameter. This is the approach I'm taking at the moment
Although if interoperability between C# and F# projects is a requirement it would make just as much sense to use C# for EFCore...

Good thinking regarding DU's for many-types-per-table style relationships, hadn't considered these models before but a discriminated union definitely makes the most sense

@bricelam
Copy link
Member Author

Where is the reverse engineering implementation at? Can we put an alpha of it up on NuGet.org yet?

@simon-reynolds
Copy link
Collaborator

Haven't worked on reverse engineer support in a while so will have to double check later when I get a chance but if it's not good for alpha it shouldn't take long to get it there

@simon-reynolds
Copy link
Collaborator

@bricelam
Looking into this at the moment and getting this error
Unable to resolve service for type 'Microsoft.EntityFrameworkCore.Scaffolding.ProviderCodeGenerator' while attempting to activate 'Bricelam.EntityFrameworkCore.FSharp.Scaffolding.FSharpDbContextGenerator'

This is testing using Postgresql, a C# project performs the scaffold correctly

The issue appears to be here
https://github.com/aspnet/EntityFrameworkCore/blob/release/2.2/src/EFCore.Design/Design/Internal/DesignTimeServicesBuilder.cs#L89

Am I correct that currently EF Core will only load one instance of IDesignTimeServices?

@bricelam
Copy link
Member Author

One from the user’s startup assembly. There can be multiple registered via DesignTimeServicesReferenceAttribute. The msbuild script adds this attribute to the startup project.

@simon-reynolds
Copy link
Collaborator

Was able to scaffold the Northwind database without issue
At this stage I feel an alpha release can be justified

Caveats
#20 - generated files are not added to the project by default
#21 - many-types-per-table relationships are not currently supported

While #20 would not necessarily block an alpha release it is definitely something to be addressed soon as it is a major usability issue. We should not have to leave it up to the user to figure out the compilation order

Have created #23 to merge these changes

@simon-reynolds
Copy link
Collaborator

Initial support added
Everything from here on will be a new ticket

musheddev pushed a commit to musheddev/EFCore.FSharp that referenced this issue Apr 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

4 participants