随着宇宙第一IDE的最新版本发布[2017/3/7],AspNetCore 和EntityFrameworkCore(团队)都发布了最新的代码。

不过在我看来,这些到还不是最重要的。最重要的是dotnet cli终于rtm了,以及和它配套的各类工具。好鸡冻啊,终于不用管beta,preview,final,final-update之类的版本了。虽然今后一定还会有各类版本发布,但是本次发布之后,工具的很多使用方式和习惯都会定下来(一些),方便我们这种用户使用和记忆。

问题环境

为了跟进新本版,在安装了vs2017之后,我就迫不及待地搭建了一个项目进行测试。

项目

内容

EfCore11.Domain Entity类型,不需要引用其他nuget包
EfCore11.DataSqlServer DbContext项目,需要引用Microsoft.EntityFrameworkCore.SqlServer等nuget包
EfCore11.SomeUI AspnetCore MVC项目,可以通过dotnet new mvc命令生成

其中的项目文件:

Domain项目中的Blog.cs文件

  1. using System.Collections.Generic;
  2.  
  3. namespace EfCore11.Domain
  4. {
  5. public class Blog
  6. {
  7. public int Id { get; set; }
  8. public string Name { get; set; }
  9. public string Url { get; set; }
  10. public ICollection<Post> Posts { get; set; }
  11. }
  12. }

Domain项目中的Post.cs文件

  1. namespace EfCore11.Domain
  2. {
  3. public class Post
  4. {
  5. public int Id { get; set; }
  6. public string Title { get; set; }
  7. public string Body { get; set; }
  8.  
  9. public int BlogId { get; set; }
  10. public Blog Blog { get; set; }
  11. }
  12. }

DataSqlServer项目中的BlogDbContext.cs文件

  1. using EfCore11.Domain;
  2. using Microsoft.EntityFrameworkCore;
  3.  
  4. namespace EfCore11.DataSqlServer
  5. {
  6. public class BlogDbContext : DbContext
  7. {
  8. public DbSet<Post> Post { get; set; }
  9. public DbSet<Blog> Blog { get; set; }
  10.  
  11. public BlogDbContext(DbContextOptions<BlogDbContext> option)
  12. : base(option)
  13. {
  14.  
  15. }
  16. }
  17. }

SomeUI项目中Startup.cs文件中修改的代码

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. // Add framework services.
  4. services.AddMvc();
  5. // 此处不用json配置的方法了,因为不是本文的重点。如有需要请自行baidu
  6. string conn = "server=(localdb)\\mssqllocaldb;database=Ef.Core;Trusted_connection=true;";
  7. services.AddDbContext<BlogDbContext>(opt => opt.UseSqlServer(conn));
  8. }

问题0:在哪个项目上执行 code first migration 呢?

按照现在的项目机构,可以执行code first migration 的项目有两个:分别是DbContext项目,也就是本文环境中的DataSqlServer项目;以及Mvc项目,也就是本文中的SomeUI项目。

这两个项目都可以完成数据库迁移所需的操作,但是实现目有所不同。因为在哪个项目内完成迁移就意味着要由哪个项目中维护相应的迁移代码,而用于生产环境的MVC项目是不会包含全部数据库迁移代码的(理由很多了,谁也不会把包含“简历生成事件”的代码放到生产环境上的),所以通常情况下的开发项目采用DbContext项目管理迁移代码,测试环境随意。

先说简单的,在MVC环境下迁移:

问题1:执行 dotnet ef 命令错误

重现方法:CMD打开SomeUI目录,然后执行“dotnet ef”命令

报错内容:No executable found matching command "dotnet-ef"

问题解释:ef core编写时其内容被拆分成为了很多包,以方便程序员只加载程序所需的代码,这样程序就会占用更小的内存,运行速度更快,部署更容易。所以想要运行dotnet-ef命令,还需要加载Microsoft.EntityFrameworkCore.Tools.DotNet

此包的描述是这样的

处理方法:因为目前dotnet cli还没有直接添加命令行工具引用的方法,所以只能暴力一点儿了,直接修改csproj文件:

在ProjectGroup标签下直接添加:

  1. <ItemGroup>
  2. <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
  3. </ItemGroup>

//添加完毕后,如果你的vs出现了一些奇怪的现象,比如nuget包没有加载,引用不正常,可以尝试关闭当前的项目,然后重新打开项目来解决这个问题。

//看上去就是项目文件没有在修改后重新加载,希望update1的时候能够更稳定一些。

修复检查:重新执行dotnet ef,能看到独角兽啊

问题2:执行 dotnet ef migrations add initial 报错

重现方法:CMD打开SomeUI目录,执行“dotnet ef migrations add initial”

报错内容:Could not load file or assembly 'Microsoft.EntityFrameworkCore.Design, Culture=neutral, PublicKeyToken=null'. 绯荤粺鎵句笉鍒版寚瀹氱殑鏂囦欢銆

问题解释:和上一个问题一样,而且错误信息也说的比较明确,就是还缺少一个nuget包:Microsoft.EntityFrameworkCore.Design

处理方法:在cli下的添加方式是执行:dotnet add package Microsoft.EntityFrameworkCore.Design

修复检查:再次执行dotnet ef migrations add initial ,报错信息更改了:

问题3:迁移报错,需要指定包含迁移的程序集

重现方法:详见问题2

报错内容:Your target project 'xxxxx' doesn't match your migrations assembly xxxxxxxx'. Either change your target project or change your migrations assembly.

问题解释:当前执行迁移项目和包含DbContext程序集项目不一致,要么更改执行迁移操作的项目,要么修改迁移程序集。

处理方法:两条路自己选,要么切换到用DbContext程序集管理迁移代码,要么修改当前代码以适应迁移方法。错误信息里给出了一个简单的解决方法:

Change your migrations assembly by using DbContextOptionsBuilder. E.g. options.UseSqlServer(connection, b => b.MigrationsAssembly("EfCore11.SomeUI")). By default, the migrations assembly is the assembly containing the DbContext.
Change your target project to the migrations project by using the Package Manager Console's Default project drop-down list, or by executing "dotnet ef" from the directory containing the migrations project.

对应修改的代码是SomeUI项目的Startup.cs文件

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. // Add framework services.
  4. services.AddMvc();
  5. // 此处不用json配置的方法了,因为不是本文的重点。如有需要请自行baidu
  6. string conn = "server=(localdb)\\mssqllocaldb;database=Ef.Core;Trusted_connection=true;";
  7. services.AddDbContext<BlogDbContext>(opt => opt.UseSqlServer(conn
  8. ,b=>b.MigrationsAssembly("EfCore11.SomeUI")
  1. ));
  2. }

修复检查:重新执行迁移命令,成功。

之后再执行“dotnet ef database update”就可以按照现有代码迁移,创建相应的数据库了。

至此,简单的代码迁移过程完成了。不过以上流程的解决方案不用划分为三个项目也可以实现,如果想要实现复杂项目或者用于部署身缠环境的方案,还需要过以下坑。

使用DbContext项目迁移:

对于环境和代码改动需要回滚到问题0。然后使用CMD打开DataSqlServer目录。

执行 dotnet ef命令,会遇到问题1,问题2的错误,根据描述进行修改即可,不过需要注意项目已经更换,不要改错地方了  :)

问题4:ef tooling 对于.NetStandard的支持问题

重现方法:CMD执行代码迁移

报错内容:Startup project 'EfCore11.DataSqlServer.csproj' targets framework '.NETStandard'. This framework is not intended for execution and may fail to resolve runtime dependencies. If so, specify a different project using the --startup-project option and try again.

问题解释:这不是很严重的问题,所以错误用黄色显示。因为当前版本的EF 命令行工具对于.NetStandard支持有限,所以会出现一个警告信息。如果真的想要修改这个问题,目前只能通过修改csproj文件,将targetFramework修改为netcoreapp1.1.

问题5:无法初始化DbContext

重现方法:CMD执行代码迁移

报错内容:No parameterless constructor was found on 'BlogDbContext'. Either add a parameterless constructor to 'BlogDbContext' or add an implementation of 'IDbContextFactory<BlogDbContext>' in the same assembly as 'BlogDbContext'.

问题解释:因为文中的DbContext 没有给出无参构造器,要么给出无参构造器,要么实现IDbContextFactory。此处又出现了分支,按惯例,先说简单的:通过-s|—startup-project参数让mvc程序注入一个“'IDbContextFactory<BlogDbContext>”,这样DbContext 就可以正常初始化了。

相对比较复杂的方法需要修改代码,详见问题6.

处理方法:CMD执行行命令“dotnet ef migrations add initialCreate -s ..\EfCore11.SomeUI”

修复检查

问题6:实现无参构造器的DbContext参与迁移

重现方法:

   修改代码:DataSqlServer的BlogDbContext.cs文件

  1. using EfCore11.Domain;
  2. using Microsoft.EntityFrameworkCore;
  3.  
  4. namespace EfCore11.DataSqlServer
  5. {
  6. public class BlogDbContext : DbContext
  7. {
  8. public DbSet<Post> Post { get; set; }
  9. public DbSet<Blog> Blog { get; set; }
  10.  
  11. //public BlogDbContext(DbContextOptions<BlogDbContext> option)
  12. // : base(option)
  13. //{
  14.  
  15. //}
  16.  
  17. // 因为使用无参构造器,所以需要自带链接字符串
  18. protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
  19. {
  20. optionsBuilder.UseSqlServer("server=(localdb)\\mssqllocaldb;database=Ef.Core;Trusted_connection=true;");
  21. }
  22. }
  23. }

   执行命令:dotnet ef migrations add initialCreate

再执行命令:dotnet ef database update

报错内容:Could not load file or assembly 'System.Data.SqlClient, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. 绯荤粺鎵句笉鍒版寚瀹氱殑鏂囦欢銆

:Could not load file or assembly 'System.Diagnostics.DiagnosticSource, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

问题解释:错误信息不同是因为DbContext项目使用了不同的targetFramework,如果是targetFramework=netstandard1.4,则错误为无法加载System.Data.SqlClient,如果按照问题4修改了targetFramework=netcoreapp1.1,则错误为无法加载 System.Diagnostics.DiagnosticSource。

这个问题确实很奇葩,从错误信息完全不能弄清到底该怎么处理。目前ef team给出的解决办法有点儿绕,又使用了MVC项目。我相信这个解决方法只是一个临时处理措施,后期EF Team会妥善处理这个问题。

处理方法:CMD执行行命令“dotnet ef database update -s ..\EfCore11.SomeUI”     //walkaround

修复检查:执行命令时会显示创建数据库的sql语句

问题处理完毕,最终结果是

另外还想跟园子里的小伙伴们分享一个消息:

Oracle终于回应开发者们的请求了:2017年底前后开发完基于dotnet core 的ODP驱动

详情见:Statement of Direction: ODP.NET on Microsoft .NET Core

作者:豆浆不放糖

博客:https://www.cnblogs.com/soldout

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

EntityFrameworkCore v1.1.1 问题汇总的更多相关文章

  1. .NET Core & EntityFrameworkCore

    前言 .NET Core 相比于 .NET Fromework 有跨平台.轻量化且开源的优势. 在使用 EntityFrameworkCore 的时候也遇到了很多问题,至于网络上的教程嘛...大部分都 ...

  2. RIP 路由协议

    RIP动态路由选择协议 routing information protocol     IGP   小范围   路由器限制为15台  超过可能无法收敛   收敛概念  在一个域内  各个路由器知道各 ...

  3. about云资源汇总指引V1.4:包括hadoop,openstack,nosql,虚拟化

    hadoop资料 云端云计算2G基础课程 (Hadoop简介.安装与范例) 炼数成金3G视频分享下载 虚拟机三种网络模式该如何上网指导此为视频 Hadoop传智播客七天hadoop(3800元)视频, ...

  4. 测试任务汇总v1.0

    2017.08.04 整理了目前我们所在团队需要做的日常任务 定义为v1.0

  5. about云资源汇总V1,3

    mongodb文档与视频资料分享 1.mongodb1-72.mongodb8-17集含代码3.MongoDB_and_Python学习笔记4.深入学习MongoDb5.PHP&MongoDB ...

  6. Git异常:fatal: V1.0 cannot be resolved to branch.

    GitHub实战系列汇总:http://www.cnblogs.com/dunitian/p/5038719.html ———————————————————————————————————————— ...

  7. BW知识问答汇总

    什么是sap的星型结构,能不能详细讲解一下? Cube的星型结构中SID技术的优点有哪些? 什么是BW的星型结构,与传统的星型结构的区别是什么? SAP的星型结构相对于传统的星型结构优势? Cube与 ...

  8. RedHat 和 Mirantis OpenStack 产品的版本和功能汇总和对比(持续更新)

    Mirantis 和 Red Hat 作为 OpenStack 商业化产品领域的两大领军企业,在行业内有重要的地位.因此,研究其产品版本发布周期和所支持的功能,对制定 OpenStack 产品的版本和 ...

  9. 我的ORM汇总

    MyOql是我写的ORM,目前仅支持 MSSql2005+ ,从2009年到今天,已使用过不少项目,之后会写 其它关系数据库的解析器: MySql,Sqlite,Oracle 等. 代码地址(最新版) ...

随机推荐

  1. 理解Java包

    本质上,包是一个唯一命名的类的集合,将类集合到包里面的主要原因,是为了当在应用程序中使用预先编写的类时避免与类自身可能引起的明明冲突.用于包中的类名不会妨碍另一个包或程序中的类名,因为此时,包中的类名 ...

  2. Android 开发笔记___alertDialog

    public class AlertActivity extends AppCompatActivity implements OnClickListener { private TextView t ...

  3. iPad web APP 开发相关

    1.移除 browser chrome,全屏启动  <meta name="apple-mobile-web-app-capable" content="yes&q ...

  4. Problem B: 开个餐馆算算账

    Description 小明创业了!他开了一家餐馆,每天客人还挺多的.每天下班后,他都要算算今天总共收入多少钱,但是手工算太麻烦了,所以他来向你求助了. Input 第1行N>0,表示餐馆提供N ...

  5. [译]ASP.NET Core 2.0 系列文章目录

    基础篇 [译]ASP.NET Core 2.0 中间件 [译]ASP.NET Core 2.0 带初始参数的中间件 [译]ASP.NET Core 2.0 依赖注入 [译]ASP.NET Core 2 ...

  6. Python函数篇:装饰器

    装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志.性能测试.事务处理. ...

  7. win10出现"本地计算机上的MySQL57服务启动后停止"

    在window10下mysql57出现"本地计算机上的MySQL57服务启动后停止.某些服务在未由其他服务或程序使用时将自动停止"错误 环境:win10.MySQL Communi ...

  8. [Intel Edison开发板] 06、Edison开发在linux中烧写、配置、搭建开发环境

    1.前言 linux上烧写.配置.搭建Edison环境,千万不要用默认的setup tool for ubuntu!!! (即使,你用的就是ubuntu) 因为,其默认的工具会从一个坏链接下载配置文件 ...

  9. CentOS6.8系统下,ecipse下进行编辑操作,意外退出

    错误情况:centos下打开eclipse软件,点击*.java或者*.pom软件卡死,命令行终端报错误信息,稍后eclipse自动退出. 错误信息: Java: cairo-misc.c:380: ...

  10. 如何在工程中使用axis2部署webservice

    有一个最简单的方法就是把axis2.war中的内容作为Web Project的基础, 来进行开发. 不过为了更清楚的了解如何在一个已有的Web Project中嵌入axis2, 那就手动来配置.大致分 ...