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

Support for EF Core #5

Open
airomero opened this issue Mar 2, 2016 · 199 comments
Labels
Milestone

Comments

@airomero
Copy link

@airomero airomero commented Mar 2, 2016

Hi, is there any plan to support EF7? EF7 is more stable now and we love EFReversePoco, so it'd be so nice to start playing with both together. Thanks!!

@sjh37 sjh37 added the enhancement label Mar 2, 2016
@sjh37 sjh37 assigned sjh37 and unassigned sjh37 Mar 2, 2016
@sjh37

This comment has been minimized.

Copy link
Owner

@sjh37 sjh37 commented Mar 2, 2016

It's on my todo list. However, I want to get a few things out of the way before I look at EF7 / EF Core 1.0.

  1. Data Annotations
  2. Support other database, such as PostgreSql and MySql.
@reader-man

This comment has been minimized.

Copy link

@reader-man reader-man commented May 19, 2016

@sjh37 Thanks on your great project.

I started on a new GUI, to handle All the properties of the reverse poco, and any other new one that might get added in the future, and handle the multiple model/poco projects in one solution, but it looks that the new projects/assignments/finance will delay that, when the time comes, its what i can give as gift to your great idea/work.

But please, add SQLite in the middle, as its almost a defecto in devices like mobiles.
and when you look at EF7, try to a have a look at it from the perspective of PCL, especially the Xamarin.Forms PCL, when code is generated.

@sjh37

This comment has been minimized.

Copy link
Owner

@sjh37 sjh37 commented May 19, 2016

Cool. Thanks and no problem, will do.

@sjh37

This comment has been minimized.

Copy link
Owner

@sjh37 sjh37 commented May 19, 2016

I cover all the options in detail in module 2 if you have a pluralsight subscription.

@reader-man

This comment has been minimized.

Copy link

@reader-man reader-man commented May 19, 2016

Thanks, your Tutorial is on my schedule of "To-See".

@alteredstudio

This comment has been minimized.

Copy link

@alteredstudio alteredstudio commented May 24, 2016

Watched your PluralSight Tutorial. My co-workers and I want to use it on Core 1.0 when it comes out next month. Can't wait for EF7 support. When I can scaffold controllers and views in MVC6 from the POCO class this will be amazing. Thanks for making such a game changing plugin!

@airomero

This comment has been minimized.

Copy link
Author

@airomero airomero commented Jul 5, 2016

Hey! Any update on this one? EF core is RTM and we can't wait for EFRPoco to support it!

@sjh37

This comment has been minimized.

Copy link
Owner

@sjh37 sjh37 commented Jul 5, 2016

Hi. Nothing started with EF7.

@reader-man

This comment has been minimized.

Copy link

@reader-man reader-man commented Jul 5, 2016

@sjh37 While its your decision alone, but i suggest:
if there going to be a move to EF7, that its better to be in another repository, with a different name, because of the too much difference, and because EF7 is still a child that might change its directions, and last, EF6 will stay dominant till people leave the windows desktop applications and the old ASP.Net, and that will take a long time, if it happens.

@cyberbobcity

This comment has been minimized.

Copy link

@cyberbobcity cyberbobcity commented Oct 19, 2016

I just learned about your generator! Really cool. Do you know if the resulting class built with your generator and EF6 can be used with Asp.Net Core and EF7?

@sjh37

This comment has been minimized.

Copy link
Owner

@sjh37 sjh37 commented Oct 19, 2016

I've never tried, but it can't be too far off.

@ErikEJ

This comment has been minimized.

Copy link
Contributor

@ErikEJ ErikEJ commented Oct 19, 2016

@cyberbobcity You can use EF6 (and the code generated by this tool) with ASP.NET Core.

@reader-man

This comment has been minimized.

Copy link

@reader-man reader-man commented Mar 29, 2017

Yes, that's what i am doing right now, and its working perfectly.
and by doing like that, we don't wast the project owner time, to think of re-doing it(EntityFramework-Reverse-POCO-Code-First-Generator) to work with .netstandard.

  • Make your normal solution that targets .Net core/netstandard e.g. 'SolutionA'
  • then add your class libraries(for me, i try to force my self to use only netstandard class libraries e.g. 'PrjHellow'.
  • add what ever you need as references/nugets, that your entities need to have reference to.

Then

  • Make another desktop solution e.g. 'SolutionA-POCO' in another new folder.
  • add a project e.g. 'PrjHellow-POCO'.
  • add to it the EntitiyFramework nuget, and the .tt+.ttinclude+.Core.ttinclude files.
  • configure ur .tt with your connection + tables, extra.
  • Run your .tt

Then

  • inside your desktop solution e.g. 'SolutionA-POCO', remove the project 'PrjHellow-POCO'.
  • Move its context and especialy the 'PrjHellow-POCO.csproj' + App.config + packages.config + Properties folder
  • comment the code in the added 'Properties\AssemblyInfo.cs'

Then

  • in your .Net core/netstandard e.g. 'SolutionA', add all he generated .cs files.

then

  • inside your desktop solution e.g. 'SolutionA-POCO', add the moved project 'PrjHellow-POCO'.

Now when ever you want to re-generate your entities, go to solution 'SolutionA-POCO', and run the .tt(s).
and your .netstandard projects will refresh with the new regenerated entities.

connecting the old with the new

@marekvse

This comment has been minimized.

Copy link

@marekvse marekvse commented Mar 30, 2017

Hi @reader-man. I'm puzzled as to how you did this without retargeting the project to full .net framework?! I tried to move the generated .cs class to my Core project targeting netcoreapp1.1 and that yielded lots of errors due to Entity.DbSet being in a completely different namespace in core and some of the other classes not even existing in the new namespace... ??

@marekvse

This comment has been minimized.

Copy link

@marekvse marekvse commented Mar 31, 2017

OK everybody loving this tool too much to give it up for cross-platform compatability when using the Angular 2 template as I've been trying to do (and finally succeeded). I do not think this tool can actually be run on .NET Core targeting netcore 1.1 (really not sure how @reader-man supposedly did that) but if you don't mind Re-targeting, in my case re-targeting the current Angular 2 project template with hot-reload etc. which after doing so throws an exception on UseWebpackDevMiddleware, then know that it has a fix. It is apparently a bug in .net which can be fixed by adding the System.Net.Http package to your project. At least it worked for me. This is the source of the info: aspnet/JavaScriptServices#802 .

@reader-man

This comment has been minimized.

Copy link

@reader-man reader-man commented Apr 1, 2017

@marekvse,
Well sorry, for the late reply, as i am too busy on several projects in the same time, desktop/asp.net core/mobile/several sicknesses :).
if i did not forget this page open, i would have not noticed the replies, as i am monitoring too many projects on github, that my inbox has lots of daily clutter.

lets begin answering:
first i am mainly talking about generating POCO classes as seen from the Picture, not the
DataContext, as that is the main problem in my projects that have hundreds of tables, and i wanted to port them to .netstandard, to have them work on multiple platforms/technologies.

and i am using several github open source projects, after i ported most of their code to .netstandard, as seen from the pics under:

01 entity called company b

02 abstracted entity a

03 abstracted entity b

04 dbcontextscope efcore

plus, i am still working on an old Reverse Poco version v2.17.1, because i have my own needs, and have changed its code, so currently its serving me ok, and till now, did not need to upgrade, which will take time, which i don't have.

for the DataContext, i will be working on it these days, and see if that is possible or not, strictly on .netstandard 1.6, and if need be, go to .net core 1.1.

my wish is for .netstandard 2.0 beta comes out, as it will speed porting and ease it.

@reader-man

This comment has been minimized.

Copy link

@reader-man reader-man commented Apr 4, 2017

ok guys @sjh37, @marekvse, @ErikEJ, @cyberbobcity, @airomero,
, thank god, managed to make the simplest entity/table to read data from a database with a DataContext in a NetStandard 1.6 project.

so now, the POCOs are in a NetStandard project and the DataContext in another NetStandard 1.6.
and i am initiating them from a .NetCore 1.1 ASP project.
as seen:
01 datacontext in netstandard

Had To change several things in Mr. Simon Hughes @sjh37 .tt files.

also added support classes to help in converting between old EF to new EF Core.
Not all Support Classes work, some of them are just surrogates for later to be filled/fixed, as i wanted to make sure that its possible before investing more time in it, if any one wants to help further, he's welcome.

Made a simple table with only integer fields as i couldn't fix the errors coming from the varchar/nvarchar fields.

thanks to projects like URF + DbContextScope.EfCore, that i also had to port them to NetStandard, this was possible.

All my current projects are here if people are interested, i don't know if i will have time to add them to github or not, as i never used it, i don't know if it will take too much time to learn and use.

Make a folder in "D:" drive, and decompress the files in the same order and same names like the included picture "02 Projects Structure.png", as they are interconnected, and i don't know if problems will arise if changed their placement.

also, the file "Simple Table.txt", has the structure of the table, as if u use different types, u might get errors.

The Folders:
A:
D:\4_PrjB\ConstructionToolsB\ConstructionToolsB.sln
This is the main Solution, that has the POCO Projects + DataContext Project + ASP.Net Core Project.
The main projects you should concentrate on are:
D:\4_PrjB\ConstructionToolsB\BAL\DOM\Company
D:\4_PrjB\ConstructionToolsB\DAL\ContextDAL\CompanyDAL

B:
D:\4_PrjB\ConstructionToolsB-POCO\ConstructionToolsB-POCO.sln
This is the where to run the .tt files, as it uses Old plain EF 6, to generate the POCO classes & the DataContext classes, and its .csproj are moved to "A" Solution folder and in the NetStandard projects, so they can generate the files and get collected immediately by the NetStandard projects.

C:
D:\4_Prj\CommonLibrariesCore\Main\Src
Main Common Libraries

D:
D:\4_Prj\CommonLibrariesCore\zOtherTools
Open Source Projects, ported to NetStandard.

The Helper projects:
D:\4_Prj\CommonLibrariesCore\Main\Src\Common\Uti\OldNet
D:\4_Prj\CommonLibrariesCore\zOtherTools\DbContextScope\src\oldNetEF
D:\4_Prj\CommonLibrariesCore\zOtherTools\DbContextScope\src\OldNetEFContext

Well I tried my best to explain most of the needed stuff, the rest is code that you can look into.

Regards.
and thanks again to @sjh37 for this great tool, especially when compared to the new .Net Core tools.

@reader-man

This comment has been minimized.

Copy link

@reader-man reader-man commented Apr 4, 2017

Sorry forget to say that

the .tt files that have changed to work for NetStandard, have the sentences above the changes:
//Added By Me
//Changed By Me

while there are other changes done other than these ones, but they are not related to NetStandard, and they are located in:
D:\4_PrjB\ConstructionToolsB\BAL\DOM\Company
D:\4_PrjB\ConstructionToolsB\DAL\ContextDAL\CompanyDAL

the .tt files are v2.17.1.

@ErikEJ

This comment has been minimized.

Copy link
Contributor

@ErikEJ ErikEJ commented Apr 4, 2017

@reader-man Have you tried the SQLite Toolbox Reverse engineer GUI (works with SQL Server, SQL Compact and SQLite) https://twitter.com/ErikEJ/status/834405829889638402 ?

@reader-man

This comment has been minimized.

Copy link

@reader-man reader-man commented Apr 4, 2017

@ErikEJ Many Thanks, i will give it a try in the coming days. 👍

The main thing about EF-Reverse-POC-Gen, is the huge number of customization/properties, that lend itself easily in complex developer needs/configurations.

So, while i did simple reversing in the past, but when i saw Mr. @sjh37 project, it was not just love at first site, but also addiction :), and by having it an option in ur project, its definitely a big plus by me.

Regards.

@marekvse

This comment has been minimized.

Copy link

@marekvse marekvse commented Apr 5, 2017

Same here.. Simple reverse-engineering tools are total pain. Simon's Reverse POCO solves so many problems with those that I have not seen anything remotely comparable with it.

@sanddigital

This comment has been minimized.

Copy link

@sanddigital sanddigital commented Sep 20, 2017

I'm just trying to find out if there is any progress on Ef Core 2.0 support? And if there is anything I can do to help make this happen?

I've traced back to here from:
#322

Thanks

@sjh37

This comment has been minimized.

Copy link
Owner

@sjh37 sjh37 commented Sep 20, 2017

Hi, a big help would be to take the generated code for northwind, and convert it for use with ef core, send it to me, i'd run a diff to see whats changed, then I could implement the change in the generator to match what you had done manually.

@nick-orr

This comment has been minimized.

Copy link

@nick-orr nick-orr commented Sep 26, 2019

@sjh37 Ah, that was the piece I was missing, using "NameHumanCase". Your example shows a different name (ClassName), perhaps you can update the example?

	// Writes optional base classes
	public string WriteBaseClasses()
	{
		// Example:
		//if (ClassName == "User")
		//    return " : IdentityUser<int, CustomUserLogin, CustomUserRole, CustomUserClaim>";
		
		// Do nothing by default
		return string.Empty;
	}
@sjh37

This comment has been minimized.

Copy link
Owner

@sjh37 sjh37 commented Sep 26, 2019

@wargmaster ah yes, sorry the comments are out of date. will fix thanks

@baoshenyi

This comment has been minimized.

Copy link

@baoshenyi baoshenyi commented Sep 26, 2019

Hi, Settting.GenerateSeparateFiles = true, cause visual studio 2019 frozen and partial files were generated after I close it by task manager. Any ideas? Thanks lots! Shenyi

@baoshenyi

This comment has been minimized.

Copy link

@baoshenyi baoshenyi commented Sep 26, 2019

I would like to provide a screenshot for it.
PartialFiles
ContextNotExist

@sjh37

This comment has been minimized.

Copy link
Owner

@sjh37 sjh37 commented Sep 26, 2019

Hi @baoshenyi Set

Settings.FileManagerType         = FileManagerType.Custom;
@baoshenyi

This comment has been minimized.

Copy link

@baoshenyi baoshenyi commented Sep 26, 2019

thank you so much, it works great! Shenyi
Any instructions about config?

@sjh37

This comment has been minimized.

Copy link
Owner

@sjh37 sjh37 commented Oct 2, 2019

Updated DropBox Link.

@sjh37

This comment has been minimized.

Copy link
Owner

@sjh37 sjh37 commented Oct 14, 2019

I have now added support for scalar-valued functions. Latest code: DropBox

@TimSirmovics

This comment has been minimized.

Copy link
Contributor

@TimSirmovics TimSirmovics commented Oct 22, 2019

Some more feedback:

Fake contexts

  1. Because Add() has not been implemented on FakeDbSet my unit tests using this method failed. I updated to use AddRange instead which works, but it is not clear from the outside interface that if you call Add() it will result in a NotImplementedException. Could Add() be implemented?
  2. The same unit tests failed once the above was resolved with a StackOverflow exception because of an infinite recursive call into FakeAsyncEnumerable IEnumerator<T> IEnumerable<T>.GetEnumerator(). I can provide sample code if needed.

Multi-targeting
I am playing around with a library that multi targets .NET Standard 2.0 and .NET Framework 4.72, using EF Core for the .NET Standard version and EF 6 for the .NET Framework version. I put two version of the generator (Ef6 and EfCore) in the same folder and set GenerateSeparateFiles = false so that all of the entities would generate with the same namespace (I could also put them in a seperate folder and set the namespace but this was ok for now). After generation I would wrap the entire generated file in #if NETSTANDARD2_0 and #if NET472 blocks respectively which seemed to work ok. The only issue is I had to manually re-add these after each regeneration. I'm not sure if this is a common requirement but is it possible to add an option specifing .NET targets for the output file(s)?

@sjh37

This comment has been minimized.

Copy link
Owner

@sjh37 sjh37 commented Oct 22, 2019

Hi @TimSirmovics

  1. Add() has now been implemented in FakeDbSet, grab the latest from the link below.
  2. Would you be able to help me get the FakeAsyncEnumerable working?

I like the idea of multi-targeting. I'll add a github issue for it and add it to my immediate todo list.

Grab the latetest code from DropBox
It evolves and gets refined almost on a daily basis. I've not been updating the version numbers in the code, however I have just now upped the version to 3.0.6 so people know it has been updated.

For ease of development, the code is not actually edited in EF.Reverse.POCO.v3.ttinclude. That file is created by an application called BuildTT which takes the code from a standard C# project and generates theEF.Reverse.POCO.v3.ttinclude. BuildTT will be included in the GitHub repository once I release the code.
image

@mikaelliljedahl

This comment has been minimized.

Copy link

@mikaelliljedahl mikaelliljedahl commented Oct 22, 2019

Some more feedback:

Fake contexts

  1. Because Add() has not been implemented on FakeDbSet my unit tests using this method failed. I updated to use AddRange instead which works, but it is not clear from the outside interface that if you call Add() it will result in a NotImplementedException. Could Add() be implemented?
  2. The same unit tests failed once the above was resolved with a StackOverflow exception because of an infinite recursive call into FakeAsyncEnumerable IEnumerator<T> IEnumerable<T>.GetEnumerator(). I can provide sample code if needed.

Multi-targeting
I am playing around with a library that multi targets .NET Standard 2.0 and .NET Framework 4.72, using EF Core for the .NET Standard version and EF 6 for the .NET Framework version. I put two version of the generator (Ef6 and EfCore) in the same folder and set GenerateSeparateFiles = false so that all of the entities would generate with the same namespace (I could also put them in a seperate folder and set the namespace but this was ok for now). After generation I would wrap the entire generated file in #if NETSTANDARD2_0 and #if NET472 blocks respectively which seemed to work ok. The only issue is I had to manually re-add these after each regeneration. I'm not sure if this is a common requirement but is it possible to add an option specifing .NET targets for the output file(s)?

Actually I multi target a Data access project using Entity Framework 6.3 and .Net Framework 4.7.2 and netstandard2.1 (using the old version), but I like the idea of easy switching over to EF Core. In EF Core 3.0 only netstandard2.1 would work so that feature would be great.

@TimSirmovics

This comment has been minimized.

Copy link
Contributor

@TimSirmovics TimSirmovics commented Oct 22, 2019

I tested by changing the generated code in my own solution and it looks to work if you remove the following from the generated FakeAsyncEnumerable<T>, as it falls back to the implementation on EnumerableQuery<T>:

IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
    return this.AsEnumerable().GetEnumerator();
}

Not sure if this works in all cases though.

@0xced

This comment has been minimized.

Copy link
Contributor

@0xced 0xced commented Oct 25, 2019

Excellent work on the v3 Simon, thanks! It even works with Visual Studio 2017 and multiple files with FileManagerType.Custom, fixing #266. 🎉

Here's some feedback about the new templates:

  • Settings.DbContextInterfaceName does not exist in Database.tt, making it difficult to discover.
  • It would be nice to split the .HasColumnType() with a condition on the presence of SqlPropertyType so that one can omit the .HasColumnType() annotation by setting column.SqlPropertyType = null in the Settings.UpdateColumn delegate:
sb.AppendFormat(".HasColumnName(@\"{0}\").HasColumnType(\"{1}\")", c.DbName, c.SqlPropertyType);

into this:

sb.AppendFormat(".HasColumnName(@\"{0}\")", c.DbName);

if (!string.IsNullOrEmpty(c.SqlPropertyType))
    sb.AppendFormat(".HasColumnType(\"{0}\")", c.SqlPropertyType);
@0xced

This comment has been minimized.

Copy link
Contributor

@0xced 0xced commented Oct 25, 2019

One more issue with the EF6 template: Database.SetInitializer{{setInitializer}}{{#newline}} must be replaced with System.Data.Entity.Database.SetInitializer{{setInitializer}}{{#newline}} or you get this error:

Member 'Database.SetInitializer(IDatabaseInitializer)' cannot be accessed with an instance reference; qualify it with a type name instead

See unable to use custom database initializer on Stack Overflow.

And one more minor nitpick: the two DbContext constructor calling base with the connection string and the first FakeDbAsyncEnumerable constructor have 12 spaces instead of 8 spaces like other constructors.

@vipasane

This comment has been minimized.

Copy link

@vipasane vipasane commented Oct 25, 2019

Looks really good so far, thanks Simon and all other for your latest efforts.
While using a empedded connection string escape sequence is not recognized:
When defining connection strings in TT-file:
Settings.ConnectionString = "Server=localhost\\SQLEXPRESS;Database=AdventureWorks2016;Trusted_Connection=True;";
Is generated as:
optionsBuilder.UseSqlServer("Server=localhost\SQLEXPRESS;Database=AdventureWorks2016;Trusted_Connection=True;");

@sjh37

This comment has been minimized.

Copy link
Owner

@sjh37 sjh37 commented Oct 25, 2019

All fixed above.
Huge thanks to everyone!
Grab the latest at DropBox

@sjh37

This comment has been minimized.

Copy link
Owner

@sjh37 sjh37 commented Oct 31, 2019

I have updated the license file in DropBox until 1st Jan 2020.

@sjh37

This comment has been minimized.

Copy link
Owner

@sjh37 sjh37 commented Nov 1, 2019

Heads-up on the latest update in DropBox. I've had to change the licence file from a .lic to a .txt file as some people were having the file blocked by a locked down windows as it's an unknown file extension. So after the next download from DropBox, change your licence file from ReversePOCO.lic to ReversePOCO.txt and let the rest of the team know. Thanks.

@agentKnipe

This comment has been minimized.

Copy link

@agentKnipe agentKnipe commented Nov 1, 2019

is there a trick to getting the latest version to work in vs2019? I set my parameters and hit save and nothing happens.

@sjh37

This comment has been minimized.

Copy link
Owner

@sjh37 sjh37 commented Nov 1, 2019

@agentKnipe Set Settings.FileManagerType = FileManagerType.Custom;

public enum FileManagerType
{
    VisualStudio, // Use this for .NET 4.x projects. It will make use of the `EF6.Utility.CS.ttinclude` to add/remove files from the Visual Studio project.
    Custom, // Use this for .NET Core projects. It will write the files directly. Visual Studio will automatically detect new files and include them in the project.
    Null // For testing only. Does nothing.
}

If you use a .Net Core project type with Settings.FileManagerType = FileManagerType.VisualStudio; VisualStudio hangs.

@agentKnipe

This comment has been minimized.

Copy link

@agentKnipe agentKnipe commented Nov 4, 2019

I have set that setting and it doesnt seem to make a difference. Does .net Standard matter? im on 2.1 and intending to use ef3.0

Settings.DatabaseType            = DatabaseType.SqlServer; 
Settings.TemplateType            = TemplateType.EfCore3;
Settings.GeneratorType           = GeneratorType.EfCore;
Settings.UseMappingTables        = false;
Settings.FileManagerType         = FileManagerType.Custom;
Settings.ConnectionStringName    = "WorkflowConnString";
Settings.DbContextName           = "WorkflowContext";
Settings.GenerateSeparateFiles   = false;
Settings.Namespace               = DefaultNamespace;
Settings.TemplateFolder          = Path.Combine(Settings.Root, "Templates");
Settings.AddUnitTestingDbContext = true;
@agentKnipe

This comment has been minimized.

Copy link

@agentKnipe agentKnipe commented Nov 4, 2019

ok, I think I got it to work. Instead of pasting the files into the folder in the file explorer I needed to past the files into the folder on the solution view. im not sure why that makes a difference, but that did the appropriate association and I was able to generate my db objects.

@agentKnipe

This comment has been minimized.

Copy link

@agentKnipe agentKnipe commented Nov 5, 2019

@sjh37 one more question... I hope. Should I need both the ConnectionString and the ConnectionStringName? Im finding that if I set the connection string name it doesnt pick up my connection, if I set the Connection String it works as expected. I would prefer to just set the name if that is possible.

@sjh37

This comment has been minimized.

Copy link
Owner

@sjh37 sjh37 commented Nov 5, 2019

@agentKnipe Yes, you need to set both.

Settings.ConnectionString is used by the generator to read your database schema. It's also placed into the generated code:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){{#newline}}
{{{#newline}}
    if (!optionsBuilder.IsConfigured){{#newline}}
    {{{#newline}}
        optionsBuilder.UseSqlServer(@""{{ConnectionString}}"");{{#newline}}
    }{{#newline}}
}{{#newline}}{{#newline}}

Settings.ConnectionStringName is placed in the generated code via a call to Settings.DefaultConstructorArgument.

    public {{DbContextName}}(){{#newline}}
{{#if HasDefaultConstructorArgument}}
        : base({{DefaultConstructorArgument}}){{#newline}}
{{/if}}
@mikaelliljedahl

This comment has been minimized.

Copy link

@mikaelliljedahl mikaelliljedahl commented Nov 5, 2019

I tried to create a new DAL class library targeting both .Net Framework 4.7.2 and .NET Standard 2.1.
To be able to target .Net Framework I tried to use EF Core 2.2, therefore setting the templatetype to:
Settings.TemplateType = TemplateType.EfCore2;

The generator runs fine, but the compiler complains about:
error CS0433: The type 'IAsyncEnumerable' exists in both 'System.Interactive.Async, Version=3.2.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263' and 'netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'

I got it to work by downgrading the target to .Net Standard 2.0 (i skipped targeting .Net Framework 4.7.2).

This might be off topic but if anyone else gets the same error, maybe this could help.

@0xced

This comment has been minimized.

Copy link
Contributor

@0xced 0xced commented Nov 7, 2019

I found another issue related to the reverse navigation data annotations: the additional annotations computed in Settings.ForeignKeyAnnotationsProcessing are not added to reverse navigations (they are only added for foreign keys).

Here's a patch to solve this issue:

--- EF.Reverse.POCO.v3.ttinclude
+++ EF.Reverse.POCO.v3.ttinclude
@@ -3099,6 +3099,7 @@
                         ReverseNavHasComment                        = Settings.IncludeComments != CommentsStyle.None && !string.IsNullOrEmpty(x.Comments),
                         ReverseNavComment                           = Settings.IncludeComments != CommentsStyle.None ? x.Comments : string.Empty,
                         AdditionalReverseNavigationsDataAnnotations = Settings.AdditionalReverseNavigationsDataAnnotations,
+                        AdditionalDataAnnotations                   = x.AdditionalDataAnnotations,
                         Definition                                  = x.Definition
                     })
                     .ToList(),
@@ -3171,6 +3172,7 @@
                         ReverseNavHasComment                        = Settings.IncludeComments != CommentsStyle.None && !string.IsNullOrEmpty(x.Comments),
                         ReverseNavComment                           = Settings.IncludeComments != CommentsStyle.None ? x.Comments : string.Empty,
                         AdditionalReverseNavigationsDataAnnotations = Settings.AdditionalReverseNavigationsDataAnnotations,
+                        AdditionalDataAnnotations                   = x.AdditionalDataAnnotations,
                         Definition                                  = x.Definition
                     })
                     .ToList(),
@@ -14649,6 +14651,7 @@ SELECT  SERVERPROPERTY('Edition') AS Edition,
         public bool ReverseNavHasComment                            { get; set; }
         public string ReverseNavComment                             { get; set; }
         public string[] AdditionalReverseNavigationsDataAnnotations { get; set; }
+        public string[] AdditionalDataAnnotations                   { get; set; }
         public string Definition                                    { get; set; }
     }
 
@@ -15825,6 +15828,10 @@ using {{this}};{{#newline}}
     [{{this}}]{{#newline}}
 {{/each}}
 
+{{#each AdditionalDataAnnotations}}
+    [{{this}}]{{#newline}}
+{{/each}}
+
     {{Definition}}{{#newline}}
 {{/each}}
 {{/if}}
@@ -16977,6 +16984,10 @@ using {{this}};{{#newline}}
     [{{this}}]{{#newline}}
 {{/each}}
 
+{{#each AdditionalDataAnnotations}}
+    [{{this}}]{{#newline}}
+{{/each}}
+
     {{Definition}}{{#newline}}
 {{/each}}
 {{/if}}
@0xced

This comment has been minimized.

Copy link
Contributor

@0xced 0xced commented Nov 7, 2019

One more thing: version 2 had Func<Table, string> WritePocoBaseClasses = t => to customize the base classes for a given table. In version 3, this has disappeared from Database.tt. WriteBaseClasses and WriteInsideClassBody are only found in the ttinclude file with no way to configure the base classes in the Database.tt file.

Here's how I solve it:

--- EF.Reverse.POCO.v3.ttinclude
+++ EF.Reverse.POCO.v3.ttinclude
@@ -3072,7 +3072,7 @@
                 ClassComment            = table.WriteComments(),
                 ExtendedComments        = table.WriteExtendedComments(),
                 ClassAttributes         = table.WriteClassAttributes(),
-                BaseClasses             = table.WriteBaseClasses(),
+                BaseClasses             = table.BaseClasses,
                 InsideClassBody         = table.WriteInsideClassBody(),
                 Columns = table.Columns
                     .Where(x => !x.Hidden)
@@ -14038,6 +14038,7 @@ SELECT  SERVERPROPERTY('Edition') AS Edition,
         public List<string> ReverseNavigationUniquePropNameClashes;
         public List<RawIndex> Indexes;
         public List<string> Attributes = new List<string>(); // List of attributes to add to this table
+        public string BaseClasses;
 
         private readonly IDbContextFilter _filter;
 
@@ -14435,17 +14436,6 @@ SELECT  SERVERPROPERTY('Edition') AS Edition,
             return sb.ToString();
         }
 
-        // Writes optional base classes
-        public string WriteBaseClasses()
-        {
-            // Example:
-            //if (NameHumanCase == "User")
-            //    return " : IdentityUser<int, CustomUserLogin, CustomUserRole, CustomUserClaim>";
-
-            // Do nothing by default
-            return string.Empty;
-        }
-
         // Writes any boilerplate stuff inside the POCO class body
         public string WriteInsideClassBody()
         {

Then I update table.BaseClasses = " : IMyInterface" in Settings.UpdateTable.

Also, this issue should be renamed to Support for EF Core.

@sjh37 sjh37 changed the title Support for EF7 Support for EF Core Nov 7, 2019
@sjh37

This comment has been minimized.

Copy link
Owner

@sjh37 sjh37 commented Nov 7, 2019

@0xced Thanks.
DropBox updated with your changes.

@sjh37

This comment has been minimized.

Copy link
Owner

@sjh37 sjh37 commented Nov 7, 2019

@0xced Just checking you got my email with your licence.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.