设定属性的约束
添加依赖
1 | <ItemGroup> |
在Model中添加约束
1 | public class League |
- 然后跟上一讲一样添加迁移,再应用到数据库中,这样就会将对Model的约束应用到数据库中
一对一、一对多、多对多
- 在EFCore中体现Model之间的关系有两种方式:
- 使用导航属性
- 在DbContext中配置
使用导航属性
1 | public class Club |
- 每一个Club都有一个League属性,因为League属性有可能是指向同一个引用,所以它跟League是属于一对多关系,当EFCore在添加迁移时,它会扫描所有的Model,然后根据导航属性去生成Model之间的关系。
在DbContext中配置
新创建一个比赛类Game来模拟多对多关系,其中Game和Player是属于多对多关系。在这两个Model之间需要一个关系实体GamePlay。
再新建一个简历类Resume来模拟一对一关系
1 | //Game |
- 在DbContext有一个OnModelCreating方法,重写它可以对Model进行一些配置,这种配置包括:对属性的约束、对属性类型的修改、添加种子数据等等。如果不在OnModelCreating方法中指定一对一的主体,那么EFCore就会随机选择一个作为主体,所以你可以再OnModelCreating方法中进行指定,这里的主体为Resume,它有一个PlayId的外键。
1 | protected override void OnModelCreating(ModelBuilder modelBuilder) |
- 然后添加迁移、应用到数据库
添加日志支持
添加依赖
- 在Linq.Data中添加控制台日志的依赖
1 | <ItemGroup> |
- 然后在DbContext中创建一个日志工厂
1 | //日志工厂,添加输出Sql语句的支持 |
- 最后在OnConfiguring方法中用UseLoggerFactory()来注册日志工厂
1 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) |
插入数据
- 当执行完
context.Leagues.Add
后,数据并没有真正地插入到数据库中,只有执行了context.SaveChanges()
这条语句时,数据才更新到了数据库中。
1 | static void Main(string[] args) |
运行后的结果:
AddRange:一次可以插入多条数据
1 | static void Main(string[] args) |
运行后的结果:
查询数据
1 | static void Main(string[] args) |
在这里需要注意:
- ToList和foreach的区别,推荐使用ToList后再遍历集合
- 在查询leagues时,Where条件中使用的是一个变量,当执行Sql时,EFCore就会为其创建一个变量,而如果使用一个固定值”Italy”的话,EFCore会直接把固定值插到条件中。
运行结果:
在DbContext中在
UseLoggerFactory
后面添加.EnableSensitiveDataLogging()
会使输出的Sql中参数的值给输出。
模糊查询
- 这里有两种写法:
- 使用Contains
- 使用EF提供的Like方法
1 | static void Main(string[] args) |
运行结果:
更多常见的有关查询的方法
- First()、FirstOrDefault():返回第一个。
- Single()、SingleOrDefault():返回单个,如果Model多于一个,就会抛出异常。
- Last() LastOrDefault():返回最后一个,使用这个方法必须对集合进行排序。
- Count()、LongCount()、Min()、Max()、Average()、Sum()
- Find():如果可以在内存中找到Model,则直接在内存中读取数据。
- 这些方法都有它们对应的异步版本,就是在方法名后面加上Async。
1 | var single = context.Leagues |
运行结果:
1 | var last = context.Leagues |
删除数据
1 | //EFCore只能删除被追踪的数据 |
运行结果:
修改数据
- 由于EFCore会自动地追踪我们创建的Model,所以当我们在进行增删改时,EFCore会帮我们把修改的情况给暂存,直到context执行
SaveChanges
时,EFCore才会把改动应用到数据库中
1 | var league = context.Leagues.First(); |
运行结果:
删除追踪和附加追踪
1 | //当执行了AsNoTracking方法后EFCore就不会对league对象进行追踪 |
运行结果:
也可以在Context中全局设置删除追踪,在构造器中加上这一句
ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
,这个功能一般不用,因为我们还是需要EFCore为我们追踪Model。
1 | public LinqDbContext() |
学习资料:B站杨旭