dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.79k stars 3.19k forks source link

Tools: Support Xamarin/MAUI Projects (currently requires separate .NET Standard class library) #7152

Open rowanmiller opened 7 years ago

rowanmiller commented 7 years ago

Tooling is explicitly blocked at the moment, so we'd need to do some work there to enable migrations.

PM> Add-Migration Test
Startup project 'Phoneword' targets framework 'MonoAndroid'. The Entity Framework Core Package Manager Console Tools don't support this framework.
BryantAvey commented 7 years ago

Just an FYI: I've been able to get tooling to work by downgrading the version in NuGet to 1.1.0-msbuild3-final, and then immediately updating it back to 1.1.0-preview4-final. Then rerun Add-Migration and gens the migration within a Xamarin Forms netstandard project.

raky291 commented 7 years ago

Anyone knows any alternative solution to this problem?

bricelam commented 7 years ago

@raky291 You should be able to create a .NET Standard Class Library to put your EF Core code in and use the tools.

raky291 commented 7 years ago

Hi @bricelam thank you

To use the EntityFrameworkCore.Tools with the .NET Standard, I needed to add a console app that references my library, and set it as the startup project.

screenshot

bricelam commented 7 years ago

Correct. You can also just use the class library if you edit the *.csproj to cross-target .NET Core:

<TargetFrameworks>netcoreapp2.0;netstandard2.0</TargetFrameworks>
rbrian commented 6 years ago

@bricelam not true. if you set the multitargeting, the other projects (or at least the UWP, i don't have the others set to build currently) give an error The project 'X' cannot be referenced. The referenced project is targeted to a different framework family (.NETCoreApp)

bricelam commented 6 years ago

Correct. We stopped recommending this due to poor cross-targeting support in other project types like UWP.

kkarakk commented 5 years ago

Is this ever going to be worked on/fixed? the official workaround of having another project where you do migrations and then copy migrations to your project isn't very clean and i've faced issues because of it(admittedly due to my own mistakes in not copying migrations/models from .net console to xamarin app)

plamenkoyovchev commented 5 years ago

Guys, what is going on with this issue ?

ajcvickers commented 5 years ago

@plamenkoyovchev This issue is in the Backlog milestone. This means that it is not going to happen for the 3.0 release. We will re-assess the backlog following the 3.0 release and consider this item at that time. However, keep in mind that there are many other high priority features with which it will be competing for resources.

plamenkoyovchev commented 5 years ago

Actually I was able to make it work after long research over the internet. Currently, the easiest way to create migrations for Xamarin.Forms is:

  1. To open *.csproj file and edit  <TargetFramework>netstandard2.0</TargetFramework>  to  <TargetFrameworks>netcoreapp2.0;netstandard2.0</TargetFrameworks> clean all projects and rebuild them separately 
  2. Open Package Manager Console and navigate to the shared project folder then set startup project to be the shared project and run command: Add-Migration MigrationName     - the migration files will be generated in Migrations folder
  3. In *.csproj file turn back the TargetFramework to reference only netstandard2.0 and don't forget to remove 's' from the tag: should be since it's referencing single framework

But now I have another problem for Xamarin.iOS the lastest SQLite version in iOS 12.2 is 3.24.0 which does not support Column Renaming. SQLite has a lot of limitaions and the miss of column renaming make it useless. It is supported in 3.26.0 but I am still not able to find how to force my Xamarin app to use dll of sqlite version 3.26.0

andrewndavis commented 5 years ago

You can get around this issue by opening the generated migration file and replace the migrationBuilder.RenameColumn command with the following: ` //Change table name so we can copy data to updated schema migrationBuilder.RenameTable(name: "MyTableWithColumnNameToChange", newName: "MyTableWithColumnNameToChangeTempName");

//Recreate table with desired new column. //I would recommend getting this from the migration script that created the table originally. //Then just rename the offending column. migrationBuilder.CreateTable( name: "MyTableWithColumnNameToChange", columns: table => new { Id = table.Column(nullable: false) .Annotation("Sqlite:Autoincrement", true), CreationTime = table.Column(nullable: false), CreatorUserId = table.Column(nullable: true), LastModificationTime = table.Column(nullable: true), MyTableColumn1 = table.Column(nullable: true), MyTableColumn2 = table.Column(nullable: false), MyTableColumn3 = table.Column(nullable: true), MyTableColumn4 = table.Column(nullable: true), MyTableColumn5 = table.Column(nullable: true), ThisIsMyRenamedColumn = table.Column(nullable: false) }, constraints: table => { table.PrimaryKey("PK_MyTableWithColumnNameToChange", x => x.Id); table.ForeignKey( name: "FK_MyTableWithColumnNameToChange_SomeOtherTable_KeyedColumn", column: x => x.KeyedColumn, principalTable: "SomeOtherTable", principalColumn: "Id", onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "FK_MyTableWithColumnNameToChange_SomeOtherTable_KeyedColumn", column: x => x.KeyedColumn, principalTable: "SomeOtherTable", principalColumn: "Id", onDelete: ReferentialAction.Restrict); }); //Move data from old table we renamed above to new table with renamed column/ migrationBuilder.Sql("INSERT INTO MyTableWithColumnNameToChange SELECT Id, CreationTime, CreatorUserId, LastModificationTime, MyTableColumn1 , MyTableColumn2, MyTableColumn3, MyTableColumn4, MyTableColumn5, ThisIsMyOldColumnName FROM MyTableWithColumnNameToChangeTempName;");

//now drop the old table with the wrong name migrationBuilder.DropTable(name: "MyTableWithColumnNameToChangeTempName");

`

Granted this is long and kinda annoying, but it's what you would have to do anyways if you were using a sqlite db running on a version prior to 3.25.0. Something to note is that foreign keys and indexes will also need to be taken into account when doing this process.

plamenkoyovchev commented 5 years ago

@andrewndavis Thanks for this. I've successfully forced iOS to not use its embedded SQLite by doing this: (https://forums.xamarin.com/discussion/153353/how-to-use-sqlite-3-26-0-instead-of-3-24-0-in-my-xamarin-forms-ios-project/)

mzhukovs commented 5 years ago

Wondering if this will be addressed directly any time soon?

ajcvickers commented 5 years ago

@mzhukovs This issue is in the Backlog milestone. This means that it is not going to happen for the 3.0 release. We will re-assess the backlog following the 3.0 release and consider this item at that time. However, keep in mind that there are many other high priority features with which it will be competing for resources.

Daxton47 commented 4 years ago

So with a relatively new release of 3.1, I see this issue was going to be re-evaluated after the 3.0 release, is there hope that this will make it into the 5.0 release this November? From the general overview of the 5.0 release, there's a note under Migrations stating

The result is likely to be many small improvements in EF Core (for example, better Migrations on SQLite)

Can we take this to be a resolution to this issue? To be honest, current workarounds for Xamarin.Forms have proved to be stable and quite easy to implement, but official support is always warmly welcomed.

bricelam commented 4 years ago

I jotted down some ideas for enabling this in https://github.com/dotnet/efcore/issues/18840

stephajn commented 3 years ago

Four and a half years later and there's still no movement on this? Wow! Is Xamarin Forms development all but abandoned in favour of MAUI?

bricelam commented 3 years ago

A big part of the MAUI effort is to bring Xamarin more fully into the main .NET experience. In .NET 6, Xamarin projects will just be normal .NET 6 projects with a more specific target. On EF, we've been waiting for this grand reconciliation to happen before deciding how best to support these workloads in our tooling.

bricelam commented 3 years ago

For up-to-date information on using EF Core with Xamarin.Forms, please see our walkthrough. But unfortunately yes, a dummy console project is still required to use Migration.

stephajn commented 3 years ago

@bricelam That walkthrough needs some love because it makes no mention about the need for the dummy console project and makes no mention of getting started with how migrations will work specifically in a Xamarin project. I will give it some praise though because it mentioned a couple of things needed in the linking behaviour, but this need for a separate console project and how to use it just isn't there. I'd suggest updating the walkthrough document to include this information.

ajcvickers commented 3 years ago

Moving this to 6.0 to investigate if we can make this a better experience for MAUI projects. However, there is a good chance that we will need to document current behavior and try to do something better in .NET 7.

bricelam commented 3 years ago

Moving this to 6.0 to investigate if we can make this a better experience for MAUI projects.

I think all the 6.0 work is already tracked by #25938

AntumArk commented 2 months ago

Is this still being worked on? feels kind of weird to have separate project just for making migrations work.

AndriySvyryd commented 1 month ago

Looks like this will fall out of scope for the EF tools. We recommend always having a separate project for migrations going forward. And we'll show a warning if you don't: #32835