【问题标题】:How to use Entity Framework 7 in class library?如何在类库中使用 Entity Framework 7?
【发布时间】:2016-08-04 22:19:28
【问题描述】:

我想用 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 中崩溃 red error=(
  • 这还不够具体。错误到底说了什么?
  • 我在帖子中添加了屏幕,我删除了方法保护覆盖无效 OnConfiguring(DbContextOptionsBuilder optionsBuilder) 和错误丢失,迁移添加了数据库,但没有表 =(,db 为空
  • 通常你不会单独得到一个 InvalidOperationException 没有其他任何东西。我怀疑这是一个错误,您可能会考虑在 GitHub 上打开一个问题。

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


【解决方案1】:

我想你错过了

"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 夜间版本中得到修复。

【讨论】:

    【解决方案2】:

    推荐的方法是将连接字符串留在应用程序的 Startup.cs 中的 AddDbContext&lt;TContext&gt;() 调用中,并使用 MigrationsAssembly() 告诉 EF 迁移的位置(可能应该在 DbContext 旁边)。例如:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-27
      • 2016-05-06
      • 1970-01-01
      • 1970-01-01
      • 2016-07-29
      相关资源
      最近更新 更多