EF在二手市场中的使用


二手市场这个小项目是我第一次用EF,边学边写边记录吧

首先明确几个知识点

存储过程

存储过程简单来说,就是为以后的使用而保存的一条或多条SQL语句的集合。可将其视为批件,虽然它们的作用不仅限于批处理。在我看来, 存储过程就是有业务逻辑和流程的集合, 可以在存储过程中创建表,更新数据, 删除等等。

 为什么要使用存储过程

通过把处理封装在容易使用的单元中,简化复杂的操作(正如前面例子所述)。由于不要求反复建立一系列处理步骤,这保证了数据的完整性。如果所有开发人员和应用程序都使用同一(试验和测试)存储过程,则所使用的代码都是相同的。这一点的延伸就是防止错误。需要执行的步骤越多,出错的可能性就越大。防止错误保证了数据的一致性。简化对变动的管理。如果表名、列名或业务逻辑(或别的内容)有变化,只需要更改存储过程的代码。使用它的人员甚至不需要知道这些变化。

数据库索引

在数据库表中,对字段建立索引可以大大提高查询速度。例如在查找username="admin"的记录 SELECT * FROM mytable WHERE username='admin';时,如果在username上已经建立了索引,MySQL无须任何扫描,即准确可找到该记录。相反,MySQL会扫描所有记录,即要查询10000条记录。

索引分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。组合索引,即一个索包含多个列。

主键会被自动建索引

数据库事务

多条sql作为一个整体提交给数据库系统,要么全部执行完成,要么全部取消。是一个不可分割的逻辑单元。

 原子性 要么都成功  要么都失败

一致性 事务执行完,数据都是正确

隔离性 两个事务同时操作一张表,B事务要么是在A事务前完成,要么在A事务完成会执行(锁表)

持久性 数据提交后 就固化下来

高并发的系统,死锁其实是不可避免的;(按照固定顺序操作数据,  事务尽量的简短;更不要在事务期间搞什么等待;降低并发;事务里面耗时短;锁的隔离级别;)

回到我们的项目

关于每张表都有一个创建人,创建时间,修改人,修改时间

这种做法是为了以后维护起来方便;如果出问题,直接可以找到最后操作该记录的人

是要看具体需求,如果业务上或者安全性上不太过在乎每个人的操作明细,那么完全可以只记录最后一笔,这样没必要分表。但是如果像银行那种账户进出明细,就有必要做一个明细表来记录了。有些业务对操作明细很注重,所以需要分表,有些仅仅是一种冗余记录,可以没必要注重那么细节。这方面你要结合你们公司的情况具体去体会

 注意模型中应有无参构造函数,不然会报错

1,创建属性映射,关系映射

可以像servicestack.ormlite一样使用特性进行标注,但是不推荐,使用FluentApi在OnModelCreating中进行配置,统一管理(我们两个一起用)

了解一下CodeFirst默认约定,可以省点力

NULL column(可空列)               EF会为所有引用类型的属性(不包含主键)创建可空数据列。

Not NULL column(不可空列)     EF为主键属性和不为空的值类型(包括日期类型)创建非空列。

 设置索引(https://www.cnblogs.com/jiangyunfeng/p/12682439.html)

 注意复杂属性ComplexType,复杂类型的每个属性都可以为空,但当作为复杂属性出现时,却是不可以为空的,必须初始化

想图片路径这些本应该是数组,该数据库无法存储此类型故,改成字符串

 2,迁移

(1)

Startup project ‘XXXXXXXX‘ targets framework ‘.NETStandard‘. There is no runtime associated with this framework, and projects targeting it cannot be executed directly. To use the Entity Framework Core Package Manager Console Tools with this project, add an executable project targeting .NET Framework or .NET Core that references this project, and set it as the startup project; or, update this project to cross-target .NET Framework or .NET Core. For more information on using the EF Core Tools with .NET Standard projects, see https://go.microsoft.com/fwlink/?linkid=2034705

在Add-Migration时出现类似错误时,看看默认启动项目是不是不是web,而是类库

 (3)

EF Core 迁移时候

没任何提示,只提示Build failed.

1检查是否是启动项目

2检查项目是否有报错的地方

 (2)

A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)

我的解决办法是修改连接字符串为  "Server=localhost;Database=XD_Market;Uid=sa;Pwd =******;"

迁移所用命令行

  Add-Migration init -c MarketContext

 Update-Database -c MarketContext

  Add-Migration init -c EventStoreSqlContext

Update-Database -c EventStoreSqlContext

3数据操作

延迟加载(Lazy Loading) 和淘宝的商品列表一样,下拉刷新,按需加载

饥饿加载 (Eager Loading) 加载父对象时同时加载子对象

显式加载 (Explicitly Loading)当我们禁用了延迟加载,仍然可以通过显式加载来延迟加载相关实体

    1,对于标签问题,标签数组存数据库是拼成一个字符串来进行存储,这里想根据一个标签进行查询,可以使用模糊查询

    2,商品分类,这个类别我们是用枚举写死了,如果做一个无极限菜单要怎么做呢(不要一级一个表)?

  (1)可以使用parentid,三级列表的parentID都记录所属的二级列表的id,这样的话就是用过递归的形式实现

  (2)和标签问题相似,采用文件夹路径那种方式,一级存为“path/id1”,二级就是“path/id1/id2”,数据库查询就用模糊查询

题外话:微博的互粉数据库应该怎么存

(1)第一个方法就是表里面有两个属性,关注人与被关注人,互粉就查询两遍看包含关系

(2)第二个

视图的概述

视图是一个虚拟表,其查询的数据来自于视图定义时的 as select xx 查询语句。视图的列来自于一个表或多个表,所以视图不可以和表名重名。
数据多用作查询,一般不会通过视图去修改数据。

项目中应该修改的一些bug

1,对于根据备注(remark)的查询,就用like  %***%模糊查询,还有一个方法是通过lucene分词保存查询

2,根据下面的建议修改索引使用(guid做主键,就用那些有意义的其他数值属性(比如价格时间)作为聚集索引)

数据库优化方案

1,分库分表(表的真实情况是硬盘的一个文件,文件越大,访问越慢)

      分表:垂直分表:就比如我们的Commodity与CommodityDetail

                 水平分表:将普通商品和悬赏分开两张表就是水平

      分库:垂直分库:按业务拆分多个库,用多个服务器来分担压力的

                 水平分库:拆分多个库,多个库结构是一样的