mrahhal / Migrator.EF6

.NET Core CLI tool to enable EF6 migrations in an Asp.Net Core app.
MIT License
82 stars 15 forks source link

Any chance to extend functionality to be able to supply a connection string and provider and/or startup project? #28

Closed DOTang closed 8 years ago

DOTang commented 8 years ago

These commands in the EF6 tooling were extremely helpful for my project setup. Basically I have a class library which contains the entity defintions, context, and API for a set of entities. My use case is allowing other programmers to use my API. I've abstracted as much of EF as I can since my API wraps it and they don't care about that. However, this means I am supplying my context connection string at run time like this:

public MyApiDbContext() : base(ApiInitializer.GetConnectionStringName())

and my initializer has them call a command `ApiInitializer.Initialize(connectionStringName) in app startup. This allows my API library to be DB agnostic and anyone wanting to utilize my entities can do so. But this setup doesn't work with your tools. It would work in EF6 tools normally by allowing to specify the startup project as the actual web app and then supplying the connection string name. Or also work by just supplying the full connection string and provider string manually in the migrate command. Any chance you could implement either of those?

Awesome library and thank you, can't believe MS has had no tooling in class libraries for over 9 months still and no ability to run tooling on EF6 in .NET CORE. Too long for very common scenarios.

mrahhal commented 8 years ago

Can't believe MS has had no tooling in class libraries for over 9 months still and no ability to run tooling on EF6 in .NET CORE. Too long for very common scenarios.

Yeah well, I've been following the problem right from the start and I just have no clue what's going on. MS seems to be completely ignoring this. Migrator.EF6 does solve the problem but I certainly don't believe that everybody who's facing this has found about it (still not as popular as you'd think, especially that EF Core is basically unusable at this stage). Maybe it's because they stated way back that the EF6 PS scripts will work in RTM so no need for an EF6 .Net Core cli tool. I don't really know what to say.

Anyway

Let me try to better understand what you're trying to do. So, you have a library that contains your entities + DbContext. Your consumers will initialize your library at startup with the connection string so you can't really hard code it inside your DbContext, and "Migrator.EF6" won't work otherwise.

Alright, I guess what you're looking for is something like:

dotnet ef migrations add InitialCreate --connection-string "..."

This is supposed to be called by your consumers, right? (But this does mean that your consumers will have to know about EF migrations even though you're abstracting EF itself, right?)

DOTang commented 8 years ago

You got it correct. And you're right, unfortunately due to how EF works, I can't abstract 100% of it, but really the only thing my consumers will be doing is running update database command pointing to the API context. But I am abstracting everything else about it hehe. So yes supplying the connection string (and provider like "System.Data.SqlClient" in the current tooling if required) would be helpful.

mrahhal commented 8 years ago

Right, can be done. But you'll have to supply your DbContext with 2 ctors, one default, and another one that takes a connection string. What I'm thinking is, if you call dotnet ef with a --connection-string option for example, it'll look for the ctor that takes a string and call it with the value of that option.

And now that I think about it, there's even a better way. I can read the value from appsettings.json for example so that you don't have to always specify it. This is also useful for other situations and will make the setup easier.

Is the provider really necessary though? I can't seem to find a place where I'd have to specify it.

DOTang commented 8 years ago

I don't know if it's necessary or not, but it currently exists in the current commands:

https://coding.abel.nu/2012/03/ef-migrations-command-reference/#Add-Migration

When you supply the connection string (not connectionStringName, the full string) in the command, you also must supply the provider since EF can work with multiple types.

mrahhal commented 8 years ago

Reviewed the code for it, it's not necessary (at least for now). OK then, I'll see what I can do and I'll let you know here when I update.

mrahhal commented 8 years ago

Resolved in 0b09ab54b07050cdc423dc1df1e8560aa698bb02, included in 1.0.6.

dotnet ef database update --connection-string "connection string" --provider "provider name"

No need to change your DbContext at all, the connection string provided will override any kind of value you've given to your DbContext.

In my tests I found that using localdb won't work when you override the connection string for some reason. So you might have to use SQL Express if you're not already.

Note: you can omit the provider's name as the default will be used. For more you can add an -h and help will be showed.

Let me know if you have any trouble getting your particular scenario to work.

DOTang commented 8 years ago

You are amazing! Thank you!