如何在类库中使用Entity Framework 7?

时间:2016-04-13 16:52:43

标签: asp.net asp.net-core entity-framework-core

我想用asp.net core 1在类库中处理数据。我在类库中创建了MyDbContext

public class MyDbContext: DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<UserProfile> Profiles { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
            base.OnModelCreating(modelBuilder);

            // maybe need to add foreign key
            modelBuilder.Entity<User>()
                .HasOne(p => p.Profile)
                .WithOne(u => u.User)
                .HasForeignKey<UserProfile>(p => p.UserId);
    }
}

我在课程库中project.json

{
  "version": "1.0.0-*",
  "description": "DatabaseCore Class Library",
  "authors": [ "alex-pc" ],
  "tags": [ "" ],
  "projectUrl": "",
  "licenseUrl": "",
  "frameworks": {
    "net451": {
      "dependencies": {
        "EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final",
        "EntityFramework.Commands": "7.0.0-rc1-final"
      },
      "frameworkAssemblies": {
        "System.Runtime": "4.0.10.0",
        "System.Data.Entity": "4.0.0.0",
        "System.Data": "4.0.0.0",
        "System.ComponentModel.DataAnnotations": "4.0.0.0"
      }
    }
  },

  "dependencies": {

  }
}

并在网络应用程序中更新了startup.cs

 public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        // Set up configuration sources.
        var builder = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .AddEnvironmentVariables();

        if (env.IsDevelopment())
        {

            builder.AddApplicationInsightsSettings(developerMode: true);
        }
        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; set; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddEntityFramework()
            .AddSqlServer()
            .AddDbContext<MyDbContext>(options =>
            {
                options.UseSqlServer(Configuration["Data:ConnectionString"]);
            });
        // Add framework services.
        services.AddApplicationInsightsTelemetry(Configuration);
        //services.AddAuthorization(options =>
        //{
        //    options.AddPolicy("API", policy =>
        //    {
        //        policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
        //        policy.RequireAuthenticatedUser();
        //    });
        //});
        services.AddAuthentication();
        services.AddCaching();
        services.AddMvc();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        app.UseApplicationInsightsRequestTelemetry();

        if (env.IsDevelopment())
        {
            app.UseBrowserLink();
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseIISPlatformHandler();

        app.UseApplicationInsightsExceptionTelemetry();

        app.UseStaticFiles();
        app.UseJwtBearerAuthentication(options =>
        {
            options.AutomaticAuthenticate = true;
            options.Audience = "resource_server_1";
            options.Authority = "http://localhost:4871/";
            options.RequireHttpsMetadata = false;
            options.TokenValidationParameters.ValidateLifetime = true;
        });

        // Add a new middleware issuing tokens.
        app.UseOpenIdConnectServer(options =>
        {
            options.AllowInsecureHttp = true;
            options.AuthorizationEndpointPath = PathString.Empty;
            options.TokenEndpointPath = "/connect/token";

            options.Provider = new AuthorizationProvider();
        });

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

    // Entry point for the application.
    public static void Main(string[] args) => WebApplication.Run<Startup>(args);
}

我的appsettings.json

{
  "ApplicationInsights": {
    "InstrumentationKey": ""
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Verbose",
      "System": "Information",
      "Microsoft": "Information"
    }
  },
  "Data": {
    "ConnectionString": "Data Source=DESKTOP-R3AP4AT\\SQLEXPRESS;Initial Catalog=mydb;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"
  }
}

现在我想进行迁移以创建数据库。使用cmd中的命令

 dnvm use 1.0.0-rc1-final
 dnx ef migrations add MyFirstMigration
 dnx ef database update

首先,一切都表现良好,数据库已创建,但未创建表,数据库为空。如果我添加了这段代码:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(
                @"Data Source=DESKTOP-R3AP4AT\\SQLEXPRESS;Initial Catalog=mydb;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False");
            base.OnConfiguring(optionsBuilder);
        }

错误 - 实例崩溃, 结果: cmd result

2 个答案:

答案 0 :(得分:0)

我想你错过了

"commands": {
    "ef": "EntityFramework.Commands"
},

在您图书馆的project.json

当我将EF模型移动到库中时,我按照此处的说明进行操作:http://www.jerriepelser.com/blog/moving-entity-framework-7-models-to-external-project

与此同时,我每晚都从RC1搬到RC2,图书馆的project.json看起来像这样。

{
    "version": "1.0.0-*",
    "description": "DhrData Class Library",
    "authors": [ "noox" ],
    "tags": [ "" ],
    "projectUrl": "",
    "licenseUrl": "",

    "dependencies": {
        "Microsoft.EntityFrameworkCore.Commands": "1.0.0-rc2-20270",
        "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0-rc2-20270"
    },

    "commands": {
        "ef": "EntityFramework.Commands"
    },

    "frameworks": {
        "dnx451": {
            "frameworkAssemblies": {
                "System.Reflection": ""
            }
        },
        "dnxcore50": {
            "dependencies": {           }
        }
    }
}

最近我没有使用迁移,因为在使用EF Core时我有太多的变化。相反,我创建了一个控制台应用程序,它重新创建数据库并用一些数据填充它。这已经是RC2了(你可能不需要自定义Appsettings)。

using System;
using DhrData.Models;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.PlatformAbstractions;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore;

namespace DhrConsoleApp
{
    public class Program
    {
        private IServiceProvider serviceProvider;
        public IConfiguration Configuration { get; set; }
        public AppSettings AppSettings { get; set; }  // object for custom configuration

        private void ConfigureServices(IServiceCollection serviceCollection)
        {
            // Add framework services.
            serviceCollection 
                //.AddEntityFramework()   // RC1
                .AddEntityFrameworkSqlServer()  // RC2
                .AddDbContext<DhrDbContext>(options => options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

            serviceCollection
                .AddScoped(p => new DhrDbContext(p.GetService<DbContextOptions<DhrDbContext>>()));

            serviceCollection.Configure<AppSettings>(s => Configuration.GetSection("AppSettings"));
        }

        public static void Main(string[] args)
        {
            var applicationEnvironment = PlatformServices.Default.Application;

            new Program(applicationEnvironment);
        }

        public Program(IApplicationEnvironment env)
        {
            //var loggerFactory = new LoggerFactory();
            //loggerFactory.AddConsole(LogLevel.Debug);

            // Set up configuration sources.
            var configurationBuilder = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json")
                .AddJsonFile("config.{env.EnvironmentName.ToLower()}.json", optional: true)
                .AddEnvironmentVariables();

            Configuration = configurationBuilder.Build();

            // custom application settings
            AppSettings = new AppSettings();
            Configuration.GetSection("AppSettings").Bind(AppSettings);

            var serviceCollection = new ServiceCollection();
            ConfigureServices(serviceCollection);
            serviceProvider = serviceCollection.BuildServiceProvider();

            using (var dbContext = serviceProvider.GetService<DhrDbContext>())
            {
                RecreateDb(dbContext);
            }
        }

        private void RecreateDb(DhrDbContext dbContext)
        {
            Console.WriteLine("EnsureDeleted ...");
            dbContext.Database.EnsureDeleted();
            Console.WriteLine("EnsureDeleted ... Done!");
            Console.WriteLine("EnsureCreated ...");
            dbContext.Database.EnsureCreated();
            Console.WriteLine("EnsureCreated ... Done!");
            Console.WriteLine("");
        }
    }
}

如果没有必要,我不建议更新到RC2,只要它不是最终的。这是一种痛苦。但是EF RC1中存在相当多的错误,这些错误已经在RC2夜间版本中得到修复。

答案 1 :(得分:0)

建议的方法是将连接字符串保留在应用程序的Startup.cs中的AddDbContext<TContext>()调用中,并使用MigrationsAssembly()告诉EF迁移所在的位置(可能与的DbContext)。 E.g:

services.AddEntityFramework().AddDbContext<MyDbContext>(options => options
    .UseSqlServer(connectionString)
    .MigrationsAssembly(assemblyName));