asp.net core mvc - remove - EntityFramework 7(EF7) Migraciones. DbContext y StartUp Project están en diferentes ensamblajes
entity framework core remove migration (4)
Para ASP.NET Core 1.0 y EF Core 1.0
Supongamos que queremos mover nuestro contexto al proyecto Core1RtmEmptyTest.DataLayer
.
Primero habilite las herramientas EF para este subproyecto modificando su archivo project.json
:
{
// same as before
"tools": {
"Microsoft.EntityFrameworkCore.Tools": {
"version": "1.0.0-preview2-final",
"imports": [
"portable-net45+win8"
]
}
},
// same as before
}
Luego ejecute el comando desde la raíz de este nuevo proyecto (y no desde la raíz del proyecto principal)
D:/path/Core1RtmEmptyTest/src/Core1RtmEmptyTest.DataLayer>dotnet ef --startup-project ../Core1RtmEmptyTest/ migrations add InitialDatabase
Aquí deberíamos especificar el startup-project
también.
Y por último actualizar la base de datos.
D:/path/Core1RtmEmptyTest/src/Core1RtmEmptyTest.DataLayer>dotnet ef --startup-project ../Core1RtmEmptyTest/ database update
Estoy intentando utilizar migraciones en EF7 con entityframework.commands. Pero mi DbContext está en un ensamblaje diferente con el proyecto de Inicio (asp.net mvc es un proyecto de inicio y Core.Implementation tiene un DbContex).
dnx migración de ef agregar MyMigration -c MyContext
System.InvalidOperationException: no se encontró DbContext llamado ''MyContext''.
He intentado usar el espacio de nombres para apuntar a otro ensamblaje, pero tampoco funcionó. ¿Es posible en absoluto? ¿O simplemente tengo que poner mi contexto en ensamblador donde está el comando ef7?
Tengo una solución alternativa, pero estoy usando EFCore 1.0.0, así que debes migrar. Debajo de los códigos que necesitas para que funcione:
La idea es tener un centro de datos central: MigrationsDataContext
para manejar migraciones de bases de datos completas. Por lo tanto, puede colocar esta migración en un proyecto separado dedicado solo para migrar la base de datos. Solo debe hacer que MigrationsDataContext
vea otros proyectos que contengan datacontexts requeridos. De esta manera, puede crear una instancia de los demás datos de contexto y llamar OnModelCreating
método OnModelCreating
manualmente pasando el ModelBuilder
actual de DbContext como parámetro.
public class MigrationsDataContext : DbContext
{
private readonly Dictionary<Type, DbContextOptions> dbCtxOpts;
private readonly IEnumerable<Type> dbCtxTypes = new[] {
typeof(CoreDataContext),
typeof(DbContext1),
typeof(DbContext2),
};
public MigrationsDataContext(DbContextOptions<MigrationsDataContext> options,
IEnumerable<DbContextOptions> dbCtxOpts)
:base(options)
{
this.dbCtxOpts = dbCtxOpts
.GroupBy(o => o.ContextType)
.ToDictionary(g => g.Key, g => g.First());
}
public MigrationsDataContext()
{ }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
foreach (var db in dbCtxTypes.Select(t => new { Type = t, Instance = Activator.CreateInstance(t, dbCtxOpts[t]) }))
{
var configurator = db.Type.GetMethod(nameof(OnModelCreating), BindingFlags.NonPublic | BindingFlags.Instance);
configurator.Invoke(db.Instance, new[] { builder });
}
}
}
Para recibir todas las DbContextOptions del constructor, debe registrar todo el paquete de DbContextOptions<T>
como DbContextOptions
esto se logra llamando al siguiente método en ConfigureServices
en Startup.cs
:
public static IServiceCollection AddBundle<T>(this IServiceCollection services)
{
var baseType = typeof(T);
var bundle = services
.Where(d => baseType.GetTypeInfo().IsAssignableFrom(d.ServiceType))
.Select(d => d.ServiceType)
.ToList();
foreach (var ctxType in bundle)
services.AddScoped(baseType, s => s.GetService(ctxType));
return services;
}
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services
.AddEntityFrameworkSqlServer()
.AddDbContext<CoreDataContext>(ConfigEf)
.AddDbContext<DbContext1>(ConfigEf)
.AddDbContext<DbContext2>(ConfigEf)
.AddDbContext<MigrationsDataContext>(ConfigEf)
.AddBundle<DbContextOptions>()
.AddBundle<DbContext>();
...
Eso es todo. Ahora gestionas las migraciones de esta manera:
mueva a su proyecto de Migraciones, adyacente al proyecto MyWebApp,
`$> dotnet ef --startup-project ../MyWebApp migrations add Initial --context Migrations.MigrationsDataContext`
Espero que esto ayude.
EDITAR
Desde 1.0.0-rc1-final (tal vez antes) este trabajo es innecesario
- Ahora no necesita
App.DataAccess/Startup.cs
(solo elimínelo si usó la solución a continuación) - Usted crea / ejecuta migraciones desde su proyecto principal (en este caso,
App.Web
) - Sin embargo, debe especificar el proyecto (
-p
paramater) que contiene migraciones:
cd App.Web
dnx ef migrations add NewMigration -p App.DataAccess
Si tiene múltiples contextos de base de datos, también tiene que especificar cuál usar (parámetro -c
)
cd App.Web
dnx ef migrations add NewMigration -p App.DataAccess -c YourDbContext
Fin de edición
Descubrí una solución para eso
Supongamos que tiene 2 proyectos: App.Web
y App.DataAccess
Puedes agregar una clase de inicio muy básica a tu App.DataAccess
:
>App.Web
-->Startup.cs // your main startup
>App.DataAccess
-->path/to/ApplicationDbContext.cs
-->different/path/to/YourModels.cs
-->Startup.cs // add a simple startup class
-->project.json
La clase de inicio simple ( App.DataAccess/Startup.cs
):
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.Data.Entity;
using Microsoft.Dnx.Runtime;
using Microsoft.Framework.Configuration;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.Logging;
namespace App.DataAccess
{
public class Startup
{
public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{
var builder = new ConfigurationBuilder(appEnv.ApplicationBasePath)
.AddJsonFile("../App.Web/config.json"); // path to your original configuration in Web project
Configuration = builder.Build();
}
public IConfiguration Configuration { get; set; }
public void ConfigureServices(IServiceCollection services)
{
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
}
}
}
A continuación, modifique su project.json en App.DataAccess ( App.DataAccess/project.json
):
{
"version": "1.0.0-*",
"description": "App.DataAccess Class Library",
"authors": [ "Author" ],
"tags": [ "" ],
"projectUrl": "",
"licenseUrl": "",
"frameworks": {
"dnx451": { }
},
"dependencies": {
"EntityFramework.Commands": "7.0.0-beta7",
"Microsoft.Framework.Configuration.Json": "1.0.0-beta7",
},
"commands": {
"ef": "EntityFramework.Commands" // this line is important, it will give you access to ''dnx ef'' in command line
}
}
Todo lo que tienes que hacer es ir a App.DataAccess
y usar dnx ef
:
cd App.DataAccess
dnx ef migrations add NewMigration
dnx ef migrations remove
dnx ef database update
dnx ef ...