EntityFramework 6

3.EF6

3.1初步目录及说明

下面是用VS2013开发环境创建的项目:

说明:控制台项目类型,安装 EF版本为6.1.3 , 数据库连接字符串配置:

隐藏代码  <connectionStrings>
    <add name="DefaultConnection"
         connectionString="Data Source=.;Initial Catalog=TestDB;UID=sa;PWD=123456"
      providerName="System.Data.SqlClient" />
  </connectionStrings>

EFContext.cs代码:

隐藏代码using Consoles.EF6.Models;
using System.Data.Entity;

namespace Consoles.EF6.Repositories
{
    public class EFContext : DbContext
    {
        public EFContext() : base("DefaultConnection") { }

        public DbSet<Category> Categories { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Category>().HasKey(k => k.CategoryId) //设置主键
                .Property(q => q.CategoryName).IsRequired();//设置不能为空
        }
    }
}

注:

a.数据库上下文 构造方法 ,继承基类,其参数是DefaultConnection,配置的数据库连接字符串中name值 要一致 ;

如果name值和上下文类名(EFContext)一致的话,上下文类的构造方法也 可以省略 .

b.为了保持实体类" 干净 ",不使用 DataAnnotations 数据注解特性,改为 Fluent API 配置方式.当然有些已经默认了,我们照样进行配置.

如:属性为 Id(字母不分大小写)或为类名+Id ,它会默认为主键,但我们也配置:Entity<Category>().HasKey(k => k.CategoryId)

疑问 :这种两种方式,到底采用那种好呢?这个……我表示无语,你自个看那个爽啦。

3.2示例一

Category.cs代码:

隐藏代码namespace Consoles.EF6.Models
{
    public class Category
    {
        public int CategoryId { get; set; }
        public string CategoryName { get; set; }
        public string Description { get; set; }
    }
}

Program.cs代码:

隐藏代码using Consoles.EF6.Models;
using Consoles.EF6.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Entity.Migrations;

namespace Consoles.EF6
{
    class Program
    {
        static void Main(string[] args)
        {
            #region 示例一
            using (var db = new EFContext())
            {
                var categories = new List<Category>
                {
                    new Category(){ CategoryName="Mobile",Description="手机大类"},
                    new Category(){ CategoryName="Computer",Description="电脑大类"}
                };

                //AddOrUpdate:根据指定列,相同就更新,不相同就添加
                categories.ForEach(list => db.Categories.AddOrUpdate(c => c.CategoryId, list));
                db.SaveChanges();

                //var query = db.Categories;
                 var query = from c in db.Categories select c;

                //遍历输出
                foreach (var item in query)
                {
                    Console.WriteLine("类别:{0};说明:{1}", item.CategoryName, item.Description);
                }
            }
            #endregion

            Console.ReadKey();
        }
    }
}

运行结果: 

查看数据库:

3.3示例二

我们添一个 Subcategory.cs ,其代码:

隐藏代码namespace Consoles.EF6.Models
{
    public class Subcategory
    {
        public int SubcategoryId { get; set; }
        public string SubcategoryName { get; set; }

        public int CategoryId { get; set; }
        public Category Category { get; set; }
    }
}

再修改 Category.cs 代码:

隐藏代码using System.Collections.Generic;

namespace Consoles.EF6.Models
{
    public class Category
    {
        public int CategoryId { get; set; }
        public string CategoryName { get; set; }
        public string Description { get; set; }

        public ICollection<Subcategory> Subcategories { get; set; }
    }
}

设计关系 为:大类Category:子类Subcategory=1:N。子类必须属于某一个大类,也就是外键不能为空。配置 Fluent API

隐藏代码using Consoles.EF6.Models;
using System.Data.Entity;

namespace Consoles.EF6.Repositories
{
    public class EFContext : DbContext
    {
        public EFContext() : base("DefaultConnection") { }

        public DbSet<Category> Categories { get; set; }
        public DbSet<Subcategory> Subcategories { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Category>().HasMany(s => s.Subcategories)
                .WithRequired(c => c.Category).HasForeignKey(f=>f.CategoryId);
            modelBuilder.Entity<Category>().HasKey(k => k.CategoryId);
            modelBuilder.Entity<Category>().Property(p => p.CategoryName).HasMaxLength(20);

            modelBuilder.Entity<Subcategory>().HasKey(K => K.SubcategoryId);
            modelBuilder.Entity<Subcategory>().Property(p => p.SubcategoryName).IsRequired();
        }
    }
}

Program.cs代码:

隐藏代码using Consoles.EF6.Models;
using Consoles.EF6.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Entity.Migrations;

namespace Consoles.EF6
{
    class Program
    {
        static void Main(string[] args)
        {
            #region 示例二
            using (var db = new EFContext())
            {
                var categories = new List<Category>
                {
                    new Category(){ CategoryName="Mobile",Description="手机大类"},
                    new Category(){ CategoryName="Computer",Description="电脑大类"}
                };
                categories.ForEach(list => db.Categories.AddOrUpdate(c => c.CategoryId, list));
                db.SaveChanges();

                var subcategories = new List<Subcategory>
                {
                    new Subcategory(){ SubcategoryName="2G",Category=db.Categories.Single(c=>c.CategoryName=="Mobile")},
                    new Subcategory(){ SubcategoryName="3G",Category=db.Categories.Single(c=>c.CategoryName=="Mobile")},
                    new Subcategory(){ SubcategoryName="4G",Category=db.Categories.Single(c=>c.CategoryName=="Mobile")},
                    new Subcategory(){ SubcategoryName="Desktop",Category=db.Categories.Single(c=>c.CategoryName=="Computer")},
                    new Subcategory(){ SubcategoryName="Tablet ",Category=db.Categories.Single(c=>c.CategoryName=="Computer")}
                };
                subcategories.ForEach(list => db.Subcategories.AddOrUpdate(c => c.SubcategoryId, list));
                db.SaveChanges();

                var query = from c in db.Categories select c;
                foreach (var item in query)
                {
                    Console.WriteLine("类别:{0};说明:{1}", item.CategoryName, item.Description);
                }
            }
            #endregion

            Console.ReadKey();
        }
    }
}

查看数据库:

嘎嘎! 一对多关系OK!Subcategories表的外键也不为空!

3.4示例三

我们再添加一个 Product.cs ,其代码:

隐藏代码using System.Collections.Generic;

namespace Consoles.EF6.Models
{
    public class Product
    {
        public int ProductId { get; set; }
        public string ProductName { get; set; }

        public ICollection<Subcategory> Subcategories { get; set; }
    }
}

再修改 Subcategory.cs:

隐藏代码using System.Collections.Generic;

namespace Consoles.EF6.Models
{
    public class Subcategory
    {
        public int SubcategoryId { get; set; }
        public string SubcategoryName { get; set; }

        public int CategoryId { get; set; }
        public Category Category { get; set; }

        public ICollection<Product> Products { get; set; }
    }
}

修改 EFContext.cs:

隐藏代码using Consoles.EF6.Models;
using System.Data.Entity;

namespace Consoles.EF6.Repositories
{
    public class EFContext : DbContext
    {
        public EFContext() : base("DefaultConnection") { }

        public DbSet<Category> Categories { get; set; }
        public DbSet<Subcategory> Subcategories { get; set; }
        public DbSet<Product> Products { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Category>().HasMany(s => s.Subcategories)
                .WithRequired(c => c.Category).HasForeignKey(f => f.CategoryId);
            modelBuilder.Entity<Category>().HasKey(k => k.CategoryId);
            modelBuilder.Entity<Category>().Property(p => p.CategoryName).HasMaxLength(20);

            modelBuilder.Entity<Subcategory>().HasKey(K => K.SubcategoryId);
            modelBuilder.Entity<Subcategory>().Property(p => p.SubcategoryName).IsRequired();

            modelBuilder.Entity<Product>().HasKey(k => k.ProductId);
            modelBuilder.Entity<Product>().Property(p => p.ProductName).HasMaxLength(120);

            modelBuilder.Entity<Subcategory>()
             .HasMany(c => c.Products).WithMany(p => p.Subcategories)
             .Map(t => t.MapLeftKey("SubCategoryId")
             .MapRightKey("ProductId")
             .ToTable("SubcategoryProduct"));
        }
    }
}

查看数据库:

3.5初始化数据

前面我们是在 Main 方法写的模拟数据代码,是不是不太好?在“ 第05章 ”文中,我也说过有预留的问题,在这补充一下。

添加 SampleData.cs ,其代码:

隐藏代码using Consoles.EF6.Models;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Data.Entity.Migrations;

namespace Consoles.EF6.Repositories
{
    public class SampleData : DropCreateDatabaseIfModelChanges<EFContext>
    {
        protected override void Seed(EFContext db)
        {
            var categories = new List<Category>
                {
                    new Category(){ CategoryName="Mobile",Description="手机大类"},
                    new Category(){ CategoryName="Computer",Description="电脑大类"}
                };
            categories.ForEach(list => db.Categories.AddOrUpdate(c => c.CategoryId, list));
            db.SaveChanges();

            var subcategories = new List<Subcategory>
                {
                    new Subcategory(){ SubcategoryName="2G",Category=db.Categories.Single(c=>c.CategoryName=="Mobile")},
                    new Subcategory(){ SubcategoryName="3G",Category=db.Categories.Single(c=>c.CategoryName=="Mobile")},
                    new Subcategory(){ SubcategoryName="4G",Category=db.Categories.Single(c=>c.CategoryName=="Mobile")},
                    new Subcategory(){ SubcategoryName="Desktop",Category=db.Categories.Single(c=>c.CategoryName=="Computer")},
                    new Subcategory(){ SubcategoryName="Tablet ",Category=db.Categories.Single(c=>c.CategoryName=="Computer")}
                };
            subcategories.ForEach(list => db.Subcategories.AddOrUpdate(c => c.SubcategoryId, list));
            db.SaveChanges();
        }
    }
}

注:关于多对多关系的数据添加,参加" 第05章 "示例!

添加配置节点:

这样 只要有访问数据库 时,就会初始化数据了,如:

隐藏代码using Consoles.EF6.Models;
using Consoles.EF6.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Entity.Migrations;

namespace Consoles.EF6
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var db = new EFContext())
            {
                var query = from c in db.Categories select c;
                foreach (var item in query)
                {
                    Console.WriteLine("类别:{0};说明:{1}", item.CategoryName, item.Description);
                }
            }

            Console.ReadKey();
        }
    }
}

我们并没在程序显式的代码中执行SampleData里的Seed方法,通过配置文件即可 (在不需要时,也可以 disableDatabaseInitialization 关闭).

4.EF7

4.1目录及说明

下面是用 VS2015 开发环境创建的项目:

说明:ASP.NET 5版的 WebApi 项目类型;

依赖和Commands配置:

commands之ef是迁移用的,这在“第06章”已经介绍过,这里会略过。

4.2示例

由于EF7暂时不直接支持 多对多 实体关系(也可能我了解有限),所以这里举例一对多。

Category.cs代码:

隐藏代码using System.Collections.Generic;

namespace WebApies.EF7.Models
{
    public class Category
    {
        public int CategoryId { get; set; }
        public string CategoryName { get; set; }
        public string Description { get; set; }

        public ICollection<Subcategory> Subcategories { get; set; }
    }
}

Subcategory.cs代码:

隐藏代码namespace WebApies.EF7.Models
{
    public class Subcategory
    {
        public int SubcategoryId { get; set; }
        public string SubcategoryName { get; set; }

        public int CategoryId { get; set; }
        public Category Category { get; set; }
    }
}

EFContext.cs代码:

隐藏代码using Microsoft.Data.Entity;
using WebApies.EF7.Models;
using Microsoft.Data.Entity.Metadata;

namespace WebApies.EF7.Repositories
{
    public class EFContext : DbContext
    {
        public DbSet<Category> Categories { get; set; }
        public DbSet<Subcategory> Subcategories { get; set; }

        protected override void OnConfiguring(DbContextOptions options)
        {
            options.UseSqlServer(
                "Server=(localdb)\\mssqllocaldb;Database=TestDB;Trusted_Connection=True;MultipleActiveResultSets=true");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Category>().HasMany(C => C.Subcategories).WithOne().ForeignKey(f=>f.CategoryId);
            modelBuilder.Entity<Category>().Key(k => k.CategoryId);
            modelBuilder.Entity<Category>().Property(p => p.CategoryName).MaxLength(20);

            modelBuilder.Entity<Subcategory>().Key(K => K.SubcategoryId);
            modelBuilder.Entity<Subcategory>().Property(p => p.SubcategoryName).Required();
        }
    }
}

迁移完毕后, 查看数据库:

注:MaxLength没有起作用!(完整版的sqlserver是正常的)

基架模板代码创建:

此时目录:

这是 T4模板代码,这个MVC版 的,webapi版本的还得等等了!

时间: 2024-08-25 22:18:42

EntityFramework 6的相关文章

EntityFramework 4使用存储过程分页

1 CREATE PROC usp_OrgPage_SQL 2 @pageIndex INT, 3 @pageSize INT, 4 @totalCount INT OUTPUT 5 AS 6 BEGIN 7 SET @totalCount = (SELECT COUNT(*) FROM dbo.Organization) 8 SELECT * FROM 9 ( 10 SELECT *,ROW_NUMBER() OVER(ORDER BY OrganizationID DESC)AS row F

EntityFramework 简单入个门

任何一个和数据相关的系统里,数据持久化都是一个不容忽视的问题. 一直以来,Java 平台出了很多 NB 的 ORM 框架,Hibernate.MyBatis等等..NET 平台上,ORM 框架这一块一直没有一个能吊到让几乎所有开发人员改掉以拼写 SQL 语句访问数据库的习惯. 实际上,在 .NET 平台上,也层出不穷的出现了很多类似的玩意儿,比如Nhibernate.Ibatis,还有微软的亲儿子--坑爹的 LinqToSQL.虽然这么多框架,但是真的没见过 .NET 平台的 ORM 框架能像

EntityFramework Core 1.1有哪些新特性呢?

前言 在项目中用到EntityFramework Core都是现学现用,及时发现问题及时测试,私下利用休闲时间也会去学习其他未曾遇到过或者用过的特性,本节我们来讲讲在EntityFramework Core 1.1中出现了哪些新特性供我们使用. EntityFramework Core 1.1新特性探讨 DbSet.Find 在EF 6.x中也有此方法的实现,在EF Core 1.1中也同样对此方法进行了实现,为什么要拿出来讲呢,当然也有其道理,我们一起来看看.在         public 

EntityFramework Core Raw SQL

EntityFramework Core Raw SQL 基础查询(执行SQL和存储过程) 啥也不说了,拿起键盘就是干,如下:     public class HomeController : Controller     {        private IBlogRepository _blogRepository;        public HomeController(IBlogRepository blogRepository)         {             _blo

EntityFramework 学习 一 并发

EntityFramework默认支持乐观并发 乐观并发中,实体加载后如果都没发生变化,ef保存该实体 首先,我们需要一个rowversion列为了控制student实体的并发问题,rowversion的数据类型为字节数组,rowversion像是自增id, rowversion的值在数据库当中自动添加和更新 ef将在where子句中添加rowversion列,当你进行更新操作,如果rowversion的值与where子句中的值不一致,则抛出异常 Student student1WithUser

EntityFramework Core Raw Query再叙注意事项后续

前言 话说通过EntityFramwork Core进行原始查询又出问题,且听我娓娓道来. EntityFramework Core Raw Query后续 当我们进行复杂查询时我们会通过原始查询来进行,我们定义如下ViewModel public class BlogViewModel { public int Id { get; set; } public string Name { get; set; } public string Url { get; set; } public str

entityframework.extended安装

在开始学习EF过程中,发现EF的批量更新和批量删除比较缓慢,在网上搜索到entityframework.extended 插件很好的解决了这个问题,故此想下载安装学习一下,下面是自己再安装过程中遇到的问题以及解决方法. 一.entityframework.extended 安装步骤: 出现错误提示如下: 二.解决问题方法 1.找到DNS服务器地址 再网上经过一番查找好,这篇博客给予了我启发http://blog.csdn.net/bklydxz/article/details/50967498,

EntityFramework、Dapper vs 草根框架性能

EntityFramework.Dapper vs 草根框架性能 扯淡 当前市面上 ORM 很多,有跑车型的,如 Dapper,有中规中矩型的,如 Mybatis.Net,也有重量型的,如 EntityFramework 和 NHibernate,还有一些出自草根之手的,如 Chloe.ORM.各式各样,层出不穷.试问,为何要重复造轮子?很简单,咱来自火星,目前地球上还没一款轮子适合咱这辆火星车~ 为加深对各个 ORM 框架的了解,同时也想看看咱自己的框架性能如何,也可以让对 Chloe 感兴趣

Asp.net 面向接口可扩展框架之数据处理模块及EntityFramework扩展和Dapper扩展(含干货)

面向接口数据处理模块是什么意思呢?实际上很简单,就是使用面向接口的思想和方式来做数据处理. 还提到EntityFramework和Dapper,EntityFramework和Dapper是.net环境下推崇最高的两种ORM工具. 1.EntityFramework是微软出的根正苗红的.netd的ORM工具,直接在Vs工具和Mvc框架中集成了,默认生成的项目就是使用EntityFramework的;微软也一直都在维护更新升级,最新版本最新版本都在EF7了.也迁移到了最新的.net Core平台了

EntityFramework学习

本文档主要介绍.NET开发中两项新技术,.NET平台语言中的语言集成查询技术 - LINQ,与ADO.NET中新增的数据访问层设计技术ADO.NET Entity Framework.ADO.NET的LINQ to Entity部分以LINQ为基础,为了完整性首先介绍LINQ技术. 预备知识 LINQ技术 LINQ是.NET 3.5中新增的一种技术,这个技术扩展了.NET平台上的编程语言,使其可以更加方便的进行数据查询,单纯的LINQ技术主要完成对集合对象(如System.Collection下