关于EntityFramework 7 开发学习

Entity Framework (又称ADO.NET Entity Framework) 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping) 解决方案,早期被称为 ObjectSpace,现已经包含在 Visual Studio 2008 Service Pack 1 以及 .NET Framework 3.5 Service Pack 1 中发表。

ADO.NET Entity Framework 以 Entity Data Model (EDM) 为主,将数据逻辑层切分为三块,分别为 Conceptual Schema, Mapping Schema 与 Storage Schema 三层,其上还有 Entity Client,Object Context 以及 LINQ 可以使用。

下面说下我用 EF7 开发项目的一些笔记(原创文章:详见我要源码网):

暂时开发模式

说明:The EF7 NuGet packages use some new metadata that is only supported in NuGet 2.8.3 or higher.

EF7 目前只能通过 NuGet 进行管理,所以,首先确定你的 Visual Studio 中的 NuGet 为最新版本(最低支持 2.8.3,最新版本 3.0)。

然后需要在 Tools –> NuGet Package Manager –> Package Manager Settings 中配置 Package Sources:https://www.myget.org/F/aspnetvnext/api/v2/,VS
2015 不需要进行添加。

我使用的是 VS 2015 开发的,所以 NuGet 不需要任何配置,使用 EF 之前,需要添加一个类库项目。

这是 VS 2015 中 ASP.NET 5 的三种模版,首先需要明确的是,ASP.NET 5 Class Library 项目可以在其他两个项目之前进行引用,但不能被其他非 ASP.NET 5 项目引用,相反,ASP.NET 5 项目也不能引用其他类型的类库项目,如果强行引用,就会抱下面错误:

所以说,如果你的 Web 项目为 ASP.NET 5,那你开发的所有类库项目必须为 ASP.NET 5 Class Library 类型的。

Code First 具体体现

创建 ASP.NET 5 Class Library 类型的 EF7 项目,像平常 EF 开发一样,我们需要在 EF7 项目中添加项,但你会发现,选择项模版中并没有“ADO.NET Entity Date Model”项。

EF6:

EF7:

“ADO.NET Entity Date Model”,就是“Code First Only”的具体表现,没办法,EF7 逼着你自行写实体代码。

DbContext 配置

EF7DbContext 示例代码:

using Microsoft.Data.Entity; using Microsoft.Data.Entity.Metadata; using System;

namespace EF7
{ public class EF7DbContext : DbContext
    { public DbSet<Entity> Entities { get; set; } protected override void OnConfiguring(DbContextOptions builder)
        {
            builder.UseSqlServer(@"data source=.;initial catalog=EF7Db;integrated security=True;");
        } protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Entity>()
               .ForRelational()
               .Table("Entities");
            modelBuilder.Entity<Entity>()
                .Key(n => n.Id);
            modelBuilder.Entity<Entity>()
                .Property(t => t.Id)
                .GenerateValuesOnAdd(false); base.OnModelCreating(modelBuilder);
        }
    }
}

OnModelCreating 方法没有变化,变化的是内部实现,映射配置后面讲下,OnConfiguring 是新加入的,builder.UseSqlServer 的作用就是绑定连接字符串,相当于之前版本 App.config 中的 connectionStrings,这个配置也可以在 ASP.NET 5 Web 的 Startup.cs 中进行配置,如下:

public class Startup
{ public Startup(IHostingEnvironment env)
    { // Setup configuration sources. Configuration = new Configuration()
            .AddJsonFile("config.json")
            .AddEnvironmentVariables();
    } public IConfiguration Configuration { get; set; } // This method gets called by the runtime. public void ConfigureServices(IServiceCollection services)
    { // Add EF services to the services container. services.AddEntityFramework()
            .AddSqlServer()
            .AddDbContext<CNBlogsNewsDbContext>(); //.AddDbContext<CNBlogsNewsDbContext>(options => //{ //    //options.UseSqlServer(Configuration.Get("Data:DefaultConnection:ConnectionString")); //    options.UseSqlServer(); //}); // Add MVC services to the services container. services.AddMvc(); // Uncomment the following line to add Web API servcies which makes it easier to port Web API 2 controllers. // You need to add Microsoft.AspNet.Mvc.WebApiCompatShim package to project.json // services.AddWebApiConventions(); }
}

AddEntityFramework 的配置模式有很多,比如上面配置中就不使用 EF7DbContext 中的连接字符串,而是读取 config.json 配置文件中的 ConnectionString,详细内容在 ASP.NET 5 记录中再进行说明,在 EF7DbContext 的示例代码中,我们会发现没有了 EF7DbContext 构造函数,之前都是在构造函数中写一大堆东西,比如:

public EF6DbContext()
    : base("name=EF6Db")
{ this.Configuration.LazyLoadingEnabled = false;
    Database.SetInitializer<EF6DbContext>(null);
}

这部分配置都移到 EF7DbContext 中的 OnConfiguring(DbContextOptions) 进行配置。

更多内容,请参考:Configuring a DbContext

Entity 映射关联配置

示例代码:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Entity>()
        .ForRelational()
        .Table("Entities");
    modelBuilder.Entity<Entity>()
        .Key(n => n.Id);
    modelBuilder.Entity<Entity>()
        .Property(t => t.Id)
        .GenerateValuesOnAdd(false);
    modelBuilder.Entity<ChildEntity>()
        .Key(n => n.Id);
    modelBuilder.Entity<ChildEntity>()
        .ManyToOne(n => n.Entity, t => t.ChildEntities)
        .ForeignKey(t => t.EntityId);
    base.OnModelCreating(modelBuilder);
}

对 Entity 属性的一些配置,我们也可以在属性的上面进行配置(比如 Key、Required、DataType 等),命令空间:System.ComponentModel.DataAnnotations,Table 配置是我无意间发现的,我原以为 EF7 不能对 Entity 进行表的重命名,之前我记得在 EF6 中是有 ToTable() 方法的,或者在 Entity 上面进行 Table() 属性配置,但在 EF7中改为了 ForRelational,所在程序集为:EntityFramework.Relational,GenerateValuesOnAdd
的配置说明是否为 identity,之前 EF 版本配置为:HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity),Entity 之间的关联配置:

IT经典笑语录:delphi就象吉普车,什么路上都能开,却什么路上也开不好,pb就像是卡丁车,只能在固定线路上开,到了室外 就有些不稳了,vc就象是跑车,你开的起却买不起,而且一旦发生故障,想修都找不到毛病在哪,java就像敞棚车,不管刮风下雨,还是艳阳高照,都能照开不误,vb就是摩托车了,骑的时间越长,你越痛恨它!

  • OneToOne:一对一
  • OneToMany:一对多
  • ManyToOne:多对一

EF7 Entity 之间的关联配置更加简单明了,EF 之前版本配置(HasRequired 或 HasRequired):

HasOptional(x => x.ParentMessage)
    .WithMany()
    .Map(x => x.MapKey("ParentID")) //.HasForeignKey(c => c.ParentID) .WillCascadeOnDelete(false);

Migration 问题纪录

参考:Using EF7 in Traditional .NET Applications

这是 EF7 的官方使用说明,其中有提到 Migration(迁移)的部分用法,其实很简单,总共就四步:

  1. Install-Package EntityFramework.SqlServer –Pre
  2. Install-Package EntityFramework.Commands -Pre
  3. Add-Migration MyFirstMigration
  4. Apply-Migration

EF7DbContext 并不需要任何配置,但试过之后会发现,一大堆的问题,而且解决方案也搜不到,已经困扰一两天的时间了,下面纪录下过程。

之前写过一篇 EF Code First 的博文,里面有提到 EF 代码迁移的使用方法(非 EF7 版本),大致为:

  1. Enable-Migrations
  2. Add-Migration Update-NewType-Name
  3. Update-Database

EF 7 代码迁移命令的完整说明(来自 get-help {命令名称} -full):

  1. Use-DbContext [-Context] [[-Project] ] []
  2. Add-Migration [-Name] [[-Context] ] [[-Project] ] []
  3. Apply-Migration [[-Migration] ] [[-Context] ] [[-Project] ] []
  4. Update-Database [[-Migration] ] [[-Context] ] [[-Project] ] []
  5. Script-Migration [[-From] ] [[-To] ] [[-Context] ] [[-Project] ] [-Idempotent] []

首先,按照EF7 Wiki 说明,在 Package Manager Console 中输入:Add-Migration MyFirstMigration 命令,会报如下错误:

异常完整信息:Add-Migration : The term ‘Add-Migration‘ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was in.

什么意思呢?直接说就是找不到“Add-Migration”命令,EF7 Migration 的所有命令管理都在 EntityFramework.Commands 程序集,所以我们使用 Migration 之前,都必须 NuGet 安装一下,找不到“Add-Migration”命令,这个问题困扰我很久,也没有找到相关资料,因为 Migration 的命令方式都是 PowerShell,我对这东西一窍不通,没办法,后来我尝试不使用 EF7,而是使用 EF6 进行 Migration 配置,发现是可以的,这就很奇怪,回过头再用
EF7 输入命令“Add-Migration”,就会报另一种错误:

异常完整信息:Join-Path : Cannot bind argument to parameter ‘Path‘ because it is null.At C:\Users\yuezhongxin\Desktop\ConsoleApp1\packages\EntityFramework.6.1.1\tools\EntityFramework.psm1:713 char:28

什么意思?就是因为“Path”参数问题,不能加载“Add-Migration”命令,和上面异常不同的是,这个异常给出错误地址了:“EntityFramework.6.1.1\tools\EntityFramework.psm1”,但有个问题是,我使用的是 EF7,为什么会报 EntityFramework.6.1.1 的异常,这个问题也困扰我很久,最后在一篇博文中找到答案及解决方式:Entity
Framework 5.0系列之Code First数据库迁移
,大致意思是说 Migration 命令没有加载最新版本的 EntityFramework,所以需要在 Package Manager Console 中手动配置一下:

  1. Import-Module C:\Users\yuezhongxin.kpm\packages\EntityFramework.Commands\7.0.0-beta1\tools\EntityFramework.psd1
  2. Install-Package EntityFramework.Commands -IncludePrerelease

在 EF 之前版本中 EntityFramework.psd1 文件位置都会在 EntityFramework 程序集文件中,但在 EF7 中,被分离在了 EntityFramework.Commands 程序集文件中了,第二步的作用是重新加载程序集。

异常完整信息:The names of some imported commands from the module ‘EntityFramework‘ include unapproved verbs that might make them less discoverable. To find the commands with unapproved verbs, run the Import-Module command again with the Verbose parameter. For a list
of approved verbs, type Get-Verb.

Import-Module EF6 是成功的,但 Import-Module EF7 就会出现上面的警告信息,具体原因不得而知,在 Package Manager Console 中输入“Add-Migration MyFirstMigration”命令,会出现下面异常:

异常完整信息:Add-Migration : Cannot bind argument to parameter ‘Path‘ because it is null.At line:1 char:1

但输入“get-help Add-Migration -full”命令(查看 Add-Migration 帮助信息),就会发现 Add-Migration 命令并没有任何问题,也就是说 EntityFramework.Commands 是可以使用的:

其实问题出现的原因无非就是两点:

  1. EntityFramework.Commands 中的 Migration 命令
  2. EF7DbContext 配置

网上关于 EF7 Migration 的资料实在少得可怜,这个问题我也只探究到这一步,毕竟还要做事,就纪录到这,等待后续解决!

珍贵的参考资料:

时间: 2024-08-05 19:37:34

关于EntityFramework 7 开发学习的相关文章

PHP开发学习门户帮您内推简历

如果您正在寻找一份与开发相关的工作,我可以帮您免费推荐一些相应的工作 将您的简历发送到:[email protected] 职位类型: Android工程师 PHP开发工程师 C++开发工程师 后台开发架构师 WEB前端工程师 美术设计师 Java高级工程师 -- 招聘公司: 百度 阿里巴巴 腾讯 新浪 完美世界 智明星通 乐元素 -- 自身要求: 个人文化修养高,有一定的学历 专业知识扎实,编程动手能力强 有团队合作意识,工作积极负责 具体的职位还会有其他一些特定要求,不再一一列举 欢迎正在求

Android深度探索(卷1)HAL与驱动开发学习笔记(2)

Android深度探索(卷1)HAL与驱动开发学习笔记(2) 第二章搭建Android开发环境 书中介绍了两种JDK的安装方法, 方法一: 从官网下载JDK并进行配置,解压后在终端打开profile文件来设置PATH环境变量(# soure /etc/profile),打开profile文件后输入下面的内容 export PATH=.:developer/jdk6/bin:$PATH 保存profile文件以后,有两种方法可以重新加载profile文件. 1.# sourse  /etc/pro

Android开发学习之路--网络编程之xml、json

一般网络数据通过http来get,post,那么其中的数据不可能杂乱无章,比如我要post一段数据,肯定是要有一定的格式,协议的.常用的就是xml和json了.在此先要搭建个简单的服务器吧,首先呢下载xampp,然后安装之类的就不再多讲了,参考http://cnbin.github.io/blog/2015/06/05/mac-an-zhuang-he-shi-yong-xampp/.安装好后,启动xampp,之后在浏览器输入localhost或者127.0.0.1就可以看到如下所示了: 这个就

ios开发学习资料总汇

ios开发学习资料总汇 下面是收集的一些学习资料. 1.唐巧精心整理了国内40多位iOS开发博主的博客地址列表 2.ios常见加密: 链接: http://pan.baidu.com/s/1eQTGFIE 密码: p8ay 3.

IBatis .NET 开发学习笔记&mdash;&mdash;.NET 开发环境搭建

大家好,今天给大家带来的是web应用程序配置,至于windows应用程序或者其他类型解决方案可以相同的配置,web应用程序配置文件为web.config,windows应用程序是app.config. 通过以下步骤可以建立属于你自己的环境: 1.首先,肯定是打开Visual Studio(文章后面简称VS),如果你有其他工具开发,我也不介意,反正我用VS,VS目前最新版是2013,不过我喜欢复古,所以,我目前用安装VS2010来当作教程,不管目前是多少版本了,都可以同理得到. 2.然后,新建一个

IOS开发学习笔记-(2)键盘控制,键盘类型设置,alert 对话框

一.关闭键盘,放弃第一响应者,处理思路有两种 ① 使用文本框的 Did End on Exit 绑定事件 ② UIControl on Touch 事件 都去操作 sender 的  resignFirstResponder #import <UIKit/UIKit.h> @interface ViewController : UIViewController @property (weak, nonatomic) IBOutlet UITextField *txtUserName; @pro

【web开发学习笔记】Structs2 Action学习笔记(一)

1.org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter准备和执行 2. <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> url-pattern约定熟成只写/*,没必要写*.action 3. <

Android开发学习---使用XmlPullParser解析xml文件

Android中解析XML的方式主要有三种:sax,dom和pull关于其内容可参考:http://blog.csdn.net/liuhe688/article/details/6415593 本文将主要介绍pull解析器解析xml文件,环境为ubuntu 12.04+ intelij 13.1 + android sdk 2.1 一.创建一个XML项目,步骤如下: 二.解析一个xml文件: assets/person.xml <?xml version="1.0" encodi

cocos2dx游戏开发学习笔记3-lua面向对象分析

在lua中,可以通过元表来实现类.对象.继承等.与元表相关的方法有setmetatable().__index.getmetatable().__newindex. 具体什么是元表在这里就不细说了,网上很多介绍,这里主要讲与cocos2dx相关联的部分. 在lua-binding库中extern.lua里,有如下方法: --Create an class. function class(classname, super) local superType = type(super) local c