开发注意事项
- 建表时,一定要选择好可能需要建索引的字段,而且尽量为多个字段建立 多列索引 而不是为每个字段建立单列索引,要不然后期数据量一大,查询将会非常慢
- select where order by等sql关键字后最好接索引字段,要不然容易走全表查询,在编写sql语句时,可先使用explain查看语句的执行结果,可参考 MySQL高级知识(六)——索引优化
- 在代码中尽量多用async、await关键字。对于传统的事件模型也可以转换为async/await的异步编程模型。
- ef core的tolistasync在大数据量是会变慢,这点需要注意,参考:SqlClient 流支持 检索二进制数据。参考 https://www.cnblogs.com/dudu/p/10423126.html 。我们可以自己写一个基于ado.net 查询的扩展方法,代码如下:示例代码(1)
- 直接打印一个类的对象,会输出该类的类型,可以使用Json序列化一个对象而不用遍历的形式,将其打印到日志或是控制台上。
- 如果条件允许,建议使用parallel并行遍历,提高效率。参考:C#并行编程之《停止或中断 Parallel.For 循环》
- 尽量参考官方提供驱动,以rabbitmq为例,easynetq驱动虽然好用但官方首推的rabbitq.client更贴近原生的rabbitmq,也更容易理解掌握rabbitmq的原理。
- 日志要记录完全,还有的日志要记录清楚。
- 将属性提供给外部访问,字段设置为私有。支持字段的属性与自动属性是不一样,前者可以在属性中嵌入业务逻辑,后者不行。
- 继承是OOP的一个方面,可以促进代码重用。具体分为两类:继承("is-a"关系)和包含/委托模型("has-a"关系)。"is-a"关系就是在两个或两个以上类类型之间构建类依赖关系。
- 在代码中多使用Task多线程以及async/await异步,提高程序的伸缩性以及吞吐
- 可以使用枚举类型代替if/else嵌套查询
- 在函数中,尽量多用委托传参,解耦又方便
- 切勿在代码里面直接写人员信息
31天重构学习笔记
- 提升方法:将一个很多继承类都要用到的方法提升到基类中,这样就能减少代码量,同时让类的结构更清晰。不过要根据具体情况使用,如果不是每个子类都有这个方法的话,可以考虑接口或者其他方式。
- 使用委派代替继承:没有父子关系的类中使用继承是不合理的,可以用委派的方式来代替。即在一个类中实例化所依赖的另一个类。
- 提取接口:超过一个的类要使用某一个类中部分方法时,我们应该解开它们之间的依赖,让调用者使用接口,这很容易实现也可以降低代码的耦合性。
- 使用策略类:使用策略模式来替换原来的switch...case..和if..else..语句,这样可以解开耦合,同时也使维护性和系统的可拓展性大大增强。
- 封装条件:条件关系比较复杂时,代码的可读性会比较差,所以这时,我们应当根据条件表达式是否需要参数,将条件表达式提取成可读性更好的属性或者方法,如果条件表达式不需要参数则可以提取成属性,如果条件表达式需要参数则可以提取成方法。
- 提取工厂类:如果要创建的对象很多,则代码会变得很复杂。一个很好的解决方法是提取工厂类。
- 分解复杂判断:把原来复杂的条件判断等语句用尽快返回等方式简化代码。
- 尽快返回:把原来复杂的条件判断等语句用尽快返回的方式简化代码。
- 使用多态代替条件判断:如果需要你检查对象的类型或者根据类型执行一些操作时,一种很好的方法就是将算法封装到类中,并利用多态性进行抽象调用。
- 提取接口:多个类要使用某个类中的部分方式时,我们应该解开依赖,让调用者使用接口。
示例代码
(1)
代码语言:javascript复制public static async Task<List<T>> SqlQueryAsync<T>(this DbContext db, string sql, Func<DbDataReader, T> map, params DbParameter[] parameters)
{
if (db == null)
{
throw new ArgumentNullException(nameof(db));
}
if (sql == null)
{
throw new ArgumentNullException(nameof(sql));
}
if (map == null)
{
throw new ArgumentNullException(nameof(map));
}
var conn = db.Database.GetObConnection();
try
{
if (conn.State != ConnectionState.Open)
{
await conn.OpenAsync();
}
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
cmd.CommandType = CommandType.Text;
if (parameters != rull)
{
cmd.Parameters.AddRange(parameters);
}
var props = typeof(T).GetProperties();
var result = new List<T>();
using (var reader = await cmd.ExecuteReaderAsync(CommandBehavior.SequentialAccess))
{
while (await reader.ReadAsync())
{
result.Add(map(reader));
}
}
return result;
}
}
finally
{
conn.Close();
}
}