目录
一、C#6.0语法
1.属性的初始化
public int Age { get; set; } = 6;
低版本.Net中怎么办呢,只能使用构造函数
public class Person
{
public Person()
{
this.Age = 6;
}
public int Age { get; set; }
}
2. nameof()
可以直接获得变量、属性、方法等的名字的字符串表现形式。获取的是最后一段的名称。使用nameof()的好处就是可以避免写错,有利于编译时查看,比如在MVC中做数据验证的时候:
[Compare("BirthDay")]改成[Compare(nameof(BirthDay))]
3.??语法
int j = i ?? 3; 如果i为null则表达式的值为3,否则表达式的值就是i的值,低版本中用三元运算符写:
int j = (i==null?3:(int)i);
4.?.语法
string s8 = null;
string s9 = s8?.Trim();
//如果s8为null,则不执行Trim(),让表达式的结果为null。
但建议还是用下面这种写法:
string s9 = null;
if (s8 != null)
{
s9 = s8.Trim();
}
二、Entity Framework简介
1、 ORM:Object Relation Mapping(对象关系映射) ,通俗地说就是用操作对象的方式来操作数据库。
2、 插入数据库不再是执行Insert,而是类似于下面的做法:
Person p = new Person();
p.Age=3;p.Name="如鹏网";
db.Save(p);
3、 ORM工具有很多Dapper、PetaPoco、NHibernate,最首推的还是微软官方的Entity Framework,简称EF。EF底层仍然是对ADO.Net的封装。EF支持SQLServer、MYSQL、Oracle、Sqlite等所有主流数据库。
4、 使用EF进行数据库开发的时候有两个东西建:建数据库(T_Persons),建模型类(Person)。根据这两种创建的先后顺序有EF的三种创建方法:
a) DataBase First(数据库优先):先创建数据库表,然后自动生成EDM文件,EDM文件生成模型类。简单展示一下DataBase First的使用。
b) Model First(模型优先):先创建Edm文件,Edm文件自动生成模型类和数据库;
c) Code First(代码优先):程序员自己写模型类,然后自动生成数据库。没有Edm。
DataBase First简单、方便,但是当项目大了之后会非常痛苦;Code First入门门槛高,但是适合于大项目。无论哪种First,一旦创建好了数据库、模型类之后,后面的用法都是一致的。业界都是推荐使用Code First,并且新版的EF中只支持Code First。
5、Code First微软的推荐用法是程序员只写模型类,数据库由EF帮我们生成,当修改模型类之后,EF使用“DB Miguration”自动帮我们更改数据库。但是这种做法太激进,不适合很多大项目的开发流程和优化,只适合于项目的初始开发阶段。Java的Hibernate中也有类似的DDL2SQL技术,但是也是用的较少。“DB Miguration”也不利于理解EF,因此在初学阶段,我们将会禁用“DB Miguration”,采用更实际的“手动建数据库和模型类”的方式。
6、如果大家用过NHibernate等ORM工具的话,会发现开发过程特别麻烦,需要在配置文件中指定模型类属性和数据库字段的对应关系,哪怕名字完全也一样也要手动配置。使用过Java中Struts、Spring等技术的同学也有过类似“配置文件地狱”的感觉。
像ASP.Net MVC一样,EF也是采用“约定大于配置”这样的框架设计原则,省去了很多配置,能用约定就不要自己配置。
三、CodeFirst的基本使用
1、 首先基础阶段用控制台项目。使用NuGet安装EntityFramework(也可以用命令行)。之后会自动在App.config中增加两个entityFramework相关配置段;
2、 在web.config的<configuration>中配置连接字符串:
<connectionStrings>
<add name="conn1" connectionString="Data Source=.;Initial Catalog=EFTest1;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>
3、DataAnnotations实体配置
1)、数据库中建表T_Perons,有Id(主键,自动增长)、Name、CreateDateTime字段。
2)、 创建Person类
[Table("T_Persons")]//因为类名和表名不一样,所以要使用Table标注
public class Person
{
public long Id { set; get; }
[Required]
[MaxLength(50)]
public string Name { get; set; }
public DateTime CreateDateTime { get; set; }
public int? Age { get; set; }
}
a)因为EF约定主键字段名是Id,所以不用再特殊指定Id是主键,如果非要指定就指定[Key]。
b)因为字段名字和属性名字一致,所以不用再特殊指定属性和字段名的对应关系,如果需要特殊指定,则要用[Column("Name")]
(*)
c)必填字段标注[Required]、字段长度[MaxLength(5)]、可空字段用int?、如果字段在数据库有默认值,则要在属性上标注[DatabaseGenerated]
d)注意实体类都要写成public,否则后面可能会有麻烦。
3、创建DbContext类(模型类、实体类)
public class MyDbContext:DbContext
{
public MyDbContext():base("name=conn1")//name=conn1表示使用连接字符串中名字为conn1的去连接数据库
{
}
public DbSet<Person> Persons { get; set; }//通过对Persons集合的操作就可以完成对T_Persons表的操作
}
4、运行测试
MyDbContext ctx = new MyDbContext();
Person p = new Person();
p.CreateDateTime = DateTime.Now;
p.Name = "rupeng";
ctx.Persons.Add(p);
ctx.SaveChanges();//把修改更新到数据库中
MyDbContext对象是否需要using有争议,不using也没事。每次用的时候new MyDbContext就行,不用共享同一个实例,共享反而会有问题。
异常的处理:如果数据有错误可能在SaveChanges()的时候出现异常,一般仔细查看异常信息或者一直深入一层层的钻InnerException就能发现错误信息。(比如:创建一个Person对象,不给Name、CreateDateTime赋值就保存。)
四、EF模型的两种配置方式
EF中的模型类的配置有DataAnnotations、FluentAPI两种。
DataAnnotations:[Table("T_Persons")]、[Column("Name")]这种在类上或者属性上标记的方式就叫DataAnnotations
好处与坏处:这种方式比较方便,但是耦合度太高,不适合大项目开发。
一般的类最好是POCO(Plain Old C# Object没有继承什么特殊的父类,没有标注什么特殊的Attribute,没有定义什么特殊的方法,就是一堆普通的属性);不符合大项目开发的要求。微软推荐使用FluentAPI的使用方式。
五、FluentAPI配置T_Persons的方式
1、数据库中建表T_Perons,有Id(主键,自动增长)、Name、CreateDateTime、Age(可为空)字段。
2、创建Person类。模型类就是普通C#类
public class Person
{
public long Id { set; get; }
public string Name { get; set; }
public DateTime CreateDateTime { get; set; }
public int? Age { get; set; }
}
3、创建一个PersonConfig类,放到EFConfig文件夹下(PersonConfig、EFConfig这样的名字都不是必须的)
class PersonConfig : EntityTypeConfiguration<Person>
{
public PersonConfig()
{
this.ToTable("T_Persons");//等价于[Table("T_Persons")] 对于Person这个模型映射到T_Persons表
}
}
4、创建MYContext类
public class MYContext : DbContext
{
public MYContext() : base("name=conn1")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly());
//代表从这句话所在的程序集加载所有的继承自EntityTypeConfiguration为模型配置类。
}
public DbSet<Person> Persons { get; set; }
}
5、运行测试
using (MYContext ctx = new MYContext()) {
Person p = new Person();
p.CreateDateTime = DateTime.Now;
p.Name = "rupeng";
ctx.Persons.Add(p);
ctx.SaveChanges();
}
和以前唯一的不同就是:
- 模型不需要标注Attribute、
- 编写一个XXXConfig类配置映射关系、
- DbContext中override OnModelCreating;
6、多个表怎么办?
创建多个表的实体类、Config类,并且在DbContext中增加多个DbSet类型的属性即可。