zoukankan      html  css  js  c++  java
  • Entity Fremework以及Fluentapi学习

    一.Entity Framework的入门  我这里采用的方式是数据库自己建立  然后模型类自己建立 数据库上下文类自己建立的方式 目的在于弄懂原理 其他的数据库优先等方式这里就不写了  教程有很多。

    首先创建控制台应用程序,接下来选择工具 NuGet包管理器,程序包管理控制台,默认项目选择自己要使用的项目,输入命令Install-Package EntityFramework 安装EntityFramework 。

    a.安装成功后,在appconfig中添加数据库连接字符串:

    <connectionStrings>
    <add name="connStr" connectionString="Data Source=.;Initial Catalog=test2;User ID=sa;Password=123456" providerName="System.Data.SqlClient" />
    </connectionStrings>

    b.添加模型类Person:

    [Table("T_Persons")]
    public class Person
    {
    public long Id { get; set; }
    public string Name { get; set; }
    public DateTime CreateDatetime { get; set; }
    }

    [Table("T_Persons")]用于告诉程序当前的类Person映射到数据库中的T_Persons表。因为现实中很有可能我们的数据库中的表名不一定和实体类名一致。

    c.添加数据库上下文类

    public class MyDbContext : DbContext
    {
    public MyDbContext() : base("name=connStr")
    {

    }

    public DbSet<Person> Persons { get; set; }
    }

    好了 到这里所以需要的准备工作已经完成  开始测试

    class Program
    {
    static void Main(string[] args)
    {
    try
    {
    MyDbContext db = new MyDbContext();
    Person p = new Person
    {
    Name = "五二狗",
    CreateDatetime = DateTime.Now
    };
    db.Persons.Add(p);
    db.SaveChanges();
    Console.WriteLine("添加成功");
    }
    catch(Exception ex)
    {
    Console.WriteLine($"添加失败,{ex.Message}");
    }
    Console.ReadKey();
    }
    }

    测试已经添加成功 ef测试ok。

    二.FluentApi的学习以及使用


    a.下载entityframework包并且安装

    b.配置数据库连接字符串

    c.新建模型类Person  这个模型类区别于上面的用法是这个模型类是一个纯净的模型类 没有其他的特性修饰

    public class Person
    {
    public long Id { get; set; }
    public string Name { get; set; }
    public DateTime CreateDatetime { get; set; }
    }

    d.新建文件夹EntityConfig(其他文件夹名字也可 不建也可 建文件夹只是为了方便统一管理)  文件夹下添加类PersonConfig继承EntityTypeConfiguration<Person>

    public class PersonConfig:EntityTypeConfiguration<Person>
    {
    public PersonConfig()
    {
    this.ToTable("T_Persons");
    }
    }

    其实这一段代码等同于上面的[Table("T_Persons")]特性

    e.新建数据库上下文类

    public class MyContext : DbContext
    {
    public MyContext():base("name=connStr")
    {

    }

    public DbSet<Person> Persons { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
    base.OnModelCreating(modelBuilder);
    modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly());
    }
    }

    ok  其他用法完全一致测试如下:

    class Program
    {
    static void Main(string[] args)
    {
    MyContext db = new MyContext();
    Person p = new Person { Name = "张三", CreateDatetime = DateTime.Now };
    db.Persons.Add(p);
    db.SaveChanges();
    Console.WriteLine("添加成功");
    }
    }

    三.Entity Framework 的增删改查

    try
    {
    TestDbContext ctx = new TestDbContext();
    #region 添加
    /*
    Person p1 = new Person { Name = "孔夫子", CreateDatetime = DateTime.Now };
    Console.WriteLine($"添加前Id是{p1.Id}");
    ctx.Persons.Add(p1);
    ctx.SaveChanges();
    Console.WriteLine("添加成功");
    Console.WriteLine($"添加成功后Id是{p1.Id}");
    */
    #endregion

    #region 查询
    /*
    var list = ctx.Persons.Where(x => x.Name == "孔夫子");
    foreach (var item in list)
    {
    Console.WriteLine(item);
    }

    var item = ctx.Persons.FirstOrDefault(x => x.Name == "孔夫子");
    Console.WriteLine(item);

    var item = ctx.Persons.SingleOrDefault(x => x.Name == "孔夫子");
    Console.WriteLine(item);
    */

    #endregion

    #region 删除
    /*
    var item = (from p in ctx.Persons
    where p.Name == "孔夫子"
    select p).SingleOrDefault();
    var item1 = ctx.Persons.Where(x => x.Name == "孔夫子").SingleOrDefault();
    var item2 = ctx.Persons.SingleOrDefault(x => x.Name == "孔夫子");
    if(item==null)
    {
    Console.WriteLine("已被删除");
    }
    else
    {
    ctx.Persons.Remove(item);
    ctx.SaveChanges();
    Console.WriteLine("删除成功");
    }
    */
    #endregion

    #region 修改
    /*
    var item = ctx.Persons.FirstOrDefault(x => x.Name == "五二狗");
    if (item == null)
    {
    Console.WriteLine("查无此人");
    }
    else
    {
    item.Name = "六二狗";
    }
    ctx.SaveChanges();
    Console.WriteLine(item);
    */
    #endregion
    }
    catch (Exception ex)
    {
    Console.WriteLine("出现错误 "+ex.Message);
    }

    Console.ReadKey();

     四.Entity Framework 原理和sql监控

    如何查看我们最终到数据库中运行的sql语句呢?

    #region EF原理

    a.查看执行的sql
    ctx.Database.Log = sql => { Console.WriteLine("*******Log******"+sql); };
    var perons = ctx.Persons.Where(x => x.Name == "六二狗").SingleOrDefault();
    Console.WriteLine(perons.Name);
    Console.WriteLine("结束");
    #endregion

    添加这样一段代码就可以 其中ctx.Database.Log属性是Databse类下面的一个属性,它的类型是public Action<string> Log { get; set; }。即一个参数是string类型,没有返回类型的委托

    因此我们让Log属性指向委托sql => { Console.WriteLine("*******Log******"+sql); };在程序运行过程中就可以看见具体的执行内容如下图

    其中关于dbo.__MigrationHistory的可以去掉 目前暂时用不到

    在数据库上下文类的构造函数中添加如下代码:

    public TestDbContext() : base("name=connStr")
    {
    Database.SetInitializer<TestDbContext>(null);
    }

    再次测试:

     控制台很干净了 不必要的代码都省去了。

    b.ToList()的立即执行理解

    看下面的一段代码

    #region EF原理
    ctx.Database.Log = sql => { Console.WriteLine("*******Log******"+sql); };
    var perons = ctx.Persons.Where(x => x.Name.Contains("二")).ToList();
    IEnumerable<Person> p = perons.Where(x => x.Name.StartsWith("章"));
    //Console.WriteLine(perons.Name);
    List<Person> testp = p.ToList();
    Console.WriteLine("结束");
    #endregion

    对应的执行sql

     sql只执行了对于二的查询 而章并没有参与到数据库查询中。这是因为tolist()是立即执行的。在使用了tolist()之后 ,程序已经将所有的数据加载到了内存中

    此时对章的选择已经不是针对于数据库了 而是内存中的一系列数据

    同理  加入第一次查询的结果保存到IEnumerable类型中 也会存在同样的问题   IEnumerable也会将结果加载到内存中  

    #region EF原理
    ctx.Database.Log = sql => { Console.WriteLine("*******Log******"+sql); };
    IEnumerable<Person> perons = ctx.Persons.Where(x => x.Name.Contains("二"));
    IEnumerable<Person> p = perons.Where(x => x.Name.StartsWith("章"));
    //Console.WriteLine(perons.Name);
    List<Person> testp = p.ToList();
    Console.WriteLine("结束");
    #endregion

    那么换一种方式  使用IQueryable

    #region EF原理
    ctx.Database.Log = sql => { Console.WriteLine("*******Log******"+sql); };
    IQueryable<Person> perons = ctx.Persons.Where(x => x.Name.Contains("二"));
    IQueryable<Person> p = perons.Where(x => x.Name.StartsWith("章"));
    //Console.WriteLine(perons.Name);
    List<Person> testp = p.ToList();
    Console.WriteLine("结束");
    #endregion

     可以看到 在数据库查询条件同时执行了 这样效率也当然高于先查一部分数据 然后加载到内存中  之后在内存中在对这一系列数据进行操作

     五.Entity Framework 直接执行sql

    #region EF执行sql语句
    /*
    //ctx.Database.ExecuteSqlCommand("insert into T_persons (name,createdatetime) values ('吴晓龙',GetDate())");
    //Console.WriteLine("添加成功");
    ctx.Database.Log = sql => { Console.WriteLine("*******Log******" + sql); };
    string name = Console.ReadLine();
    //ctx.Database.ExecuteSqlCommand($"insert into T_persons (name,createdatetime) values ('{name}',GetDate())");
    ctx.Database.ExecuteSqlCommand("insert into T_persons (name,createdatetime) values ({0},GetDate())",name);
    Console.WriteLine("添加成功");
    */
    #endregion

  • 相关阅读:
    IO流
    简单JSON
    开发流程
    命名规范
    策略模式
    Git的使用
    Markdown的使用
    代理模式
    装饰者模式
    POJ 2976 3111(二分-最大化平均值)
  • 原文地址:https://www.cnblogs.com/yagamilight/p/12227744.html
Copyright © 2011-2022 走看看