EntityFramework CodeFirst(2)

Profile Picture
- Published on Mar 26, 2020🌏 Public

EntityFramework

ORM(对象关系映射Object Relational Mapping,简称ORM)框架。

  • 充当了翻译角色:将我们的类操作转换成SQL去执行,而且可以支持各种数据库。
  • 充当苦力角色:负责与数据库进行数据交互,负责进行表数据和c#中类实例的转换。

一般我们使用EF,有两种开始的方式 1. 从数据库生成C#类及数据库上下文(Context)。 2. 通过C#类和数据库上下文建立数据库。

安装EntityFramework

mysql.data.entityframework,版本与mysql.data版本保持一致

从数据库建立模型类和上下文

1. 带设计器

右键添加新建项,数据-> ADO.NET实体数据模型->来自数据的EF设计器->添加新连接

添加时选择保存密码

//实例化一个数据库上下文
WindDbContext ctx = new WindDbContext();
var list2= ctx.产品.Where(s => s.供应商.公司名称.Contains("正") || s.类别.类别名称.Contains("果")).ToList();

return Json(list2,JsonRequestBehavior.AllowGet);

2. 不带设计器的

与带设计器的差别就是没有设计器相关的文件,创建出来的文件更加简洁,只有所有的表相关的类以及一个数据上下文的CS文件。

CodeFirst创建数据库

1.带设计器的

2.CodeFirst代码形式创建数据库

2.1 创建基础数据模型

Product.cs

    /// <summary>
    ///     产品
    /// </summary>
   public  class  Product
    {
        /// <summary>
        ///     Id
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        ///     产品名
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        ///     单价
        /// </summary>
        public decimal Price { get; set; }

        /// <summary>
        ///     是否启用
        /// </summary>
        public bool Enable { get; set; }
    }

Order.cs

    /// <summary>
    ///     订单
    /// </summary>
    public  class Order
    {
        /// <summary>
        ///     订单Id
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        ///     下单用户名
        /// </summary>
        public string UserName { get; set; }

        /// <summary>
        ///     产品Id
        /// </summary>
        public int ProductId { get; set; }

        /// <summary>
        ///     件数
        /// </summary>
        public int Quantity { get; set; }

        /// <summary>
        ///     总价格
        /// </summary>
        public decimal Total { get; set; }
    }

2.2 完善模型,加入主外键的导航属性

Product.cs

        /// <summary>
        ///     导航属性:产品的所有订单
        /// </summary>
        public virtual ICollection<Order> Orders { get; set; }

Order.cs

        /// <summary>
        ///     导航属性:订单对应的产品
        /// </summary>
        public virtual Product Product { get; set; }

2.3. 配置模型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity.ModelConfiguration;
using System.ComponentModel.DataAnnotations.Schema;

namespace SaleStore.Core.Models.Configurations
{
    public class ProductConfiguration : EntityTypeConfiguration<Product>
    {
        public ProductConfiguration() {
            //主键设置
            HasKey(s => s.Id);

            //设置各种属性

            //Id必填,自增
            Property(s => s.Id).IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

            //设置字符串长度,必填
            Property(s => s.Name).IsRequired().HasMaxLength(64);

            //十进制数字的存储精度
            Property(s => s.Price).HasPrecision(28, 2);

            //定义Enable在数据库中存储使用的数据类型
            Property(s => s.Enable).HasColumnType("tinyint");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SaleStore.Core.Models.Configurations
{
    public class OrderConfiguration : EntityTypeConfiguration<Order>
    {
        public OrderConfiguration() {
            HasKey(s => s.Id).Property(s => s.Id).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);

            Property(s => s.Total).HasPrecision(28, 2);

            Property(s => s.UserName).HasMaxLength(64).IsRequired();

            //设置外键关系
            //必须有一个Product,
            //产品有多个订单
            //Order通过ProductId建立外键
            //关闭级联删除
            HasRequired(s => s.Product).WithMany(s => s.Orders).HasForeignKey(s => s.ProductId).WillCascadeOnDelete(false);
        }
    }
}

2.4. 加入到数据上下文中

只有将我们刚刚写好的类加入到数据库上下文中,才算是真正跟数据库挂钩起来。

using SaleStore.Core.Models;
using SaleStore.Core.Models.Configurations;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SaleStore.Core
{
    public class StoreDbContext :DbContext
    {
        public StoreDbContext() : base("storeConnection") { 
        
        }
        /// <summary>
        ///     所有产品
        /// </summary>
        public DbSet<Product> Products { get; set; }

        /// <summary>
        ///     所有订单
        /// </summary>
        public DbSet<Order> Orders { get; set; }

        /// <summary>
        ///     重写模型创建方法,加入模型配置
        /// </summary>
        /// <param name="modelBuilder"></param>
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //加入模型配置
            modelBuilder.Configurations.Add(new ProductConfiguration());
            modelBuilder.Configurations.Add(new OrderConfiguration());
        }
    }
}

3.5 使用

web.config文件加入一条连接字符串:

  <connectionStrings>
    <add name="storeConnection" connectionString="Server=127.0.0.1;User Id=root;Password=1234;Database=StoreDB;" providerName="MySql.Data.MySqlClient"/>
  </connectionStrings>

使用:

            StoreDbContext ctx = new StoreDbContext();
            ctx.Products.Add(new Product
            {
                Enable = true,
                Price=10,
                 Name="测试产品"
            });
            ctx.SaveChanges();
            return Json(null,JsonRequestBehavior.AllowGet);