省流模式,看下对比

  1. //常规查询
  2. var query = users
  3. .WhereIf(m => m.UserName.Contains(input.UserName), !string.IsNullOrEmpty(input.UserName))
  4. .WhereIf(m => input.RoleIds.Contains(m.RoleId), input.RoleIds?.Any() ?? false)
  5. .WhereIf(m => m.Role.RoleName.Contains(input.RoleName), !string.IsNullOrEmpty(input.RoleName))
  6. .WhereIf(m => m.Sys.Any(p => p.SysName.Contains(input.SysName)), !string.IsNullOrEmpty(input.SysName))
  7. .WhereIf(m => m.Gender == input.Gender, input.Gender.HasValue)
  8. .WhereIf(m => m.CreateTime >= input.CreateTimeStart, input.CreateTimeStart.HasValue)
  9. .WhereIf(m => m.CreateTime <= input.CreateTimeEnd, input.CreateTimeEnd.HasValue);
  10. var list = query
  11. .OrderBy(m => m.RoleId).ThenBy(m => m.Tel)
  12. .Skip((input.Page - 1) * input.PageSize).Take(input.PageSize)
  13. .ToList();
  14. var total = query.Count();
  15. } {
  16. //构造器查询方式1
  17. var (list, total) =
  18. users.ToPageList(input.AddMultipleOrderBy(false, nameof(User.RoleId), nameof(User.Tel)));
  19. //构造器查询方式2
  20. var (list2, total2) = users
  21. .WhereExt(input) //.Where(input.ToExpression<User>())
  22. .OrderBy(false, nameof(User.RoleId), nameof(User.Tel)
  23. )
  24. .Page(input);
  25. }

没兴趣?那本博客到此结束。小伙伴可以到别处看看了(吐槽下,博客园的这个发布机制属实是看人脸皮和自信度了,我属于脸皮厚的,敢自己推首页)。

1.该表达式插件通过模型继承获取对应的能力。目前提供的模型有

  1. QueryModel :基础查询类

  2. PageModel:分页查询参数类(默认每页分页20条)

  3. FullQueryModel:查询模型,对比QueryModel 多了查询集合QueryItems和过滤FilterFields。前端可以在后端给与的基础上,添加查询参数,对于前端来说权限有点大,慎用(建议高级查询的时候用)。

  4. FullPageModel:查询模型,对比PageModel多了查询集合QueryItems和过滤FilterFields。慎用(原因同上)。

2.属性名约束

  1. 编号查询:编号查询最好是以Id结尾,不然如果编号为字符串的话,查询方式会以Contains形式查询。

  2. 时间格式:以 Start,End 结尾 ,生成条件为 >= 和<=。

  3. 数字范围:属性名称 以 Min,Max 结尾 ,生成条件为 >= 和<=。

  4. 字符串查询: 名字需要和表字段一致,生成条件为 Contains

3.特性约束。这部分主要为了弥补属性名的不足。可以使用特性ConditionAttribute。下面给出参数介绍以及使用例子。

  • 属性名:PropertyName

  • 属性值:Value

  • 查询方法:Condition

  • 查询类型:ConditionType(and/or)

  • 是否唯一属性名称:IsSinglePropertyName

  • 是否区分大小写:IsCaseSensitive

使用范例
  1. 导航父类查询:父类类名+英文符号.+父类的属性名。如

  1. [Condition($"{nameof(NewType)}.{nameof(NewType.Name)}")]
  2. public string Name { get; set; }
  1. 导航子类查询:子类类名+括号[子类属性名]。如

  1. [Condition($"{nameof(NewType)}[{nameof(NewType.Name)}]")]
  2. public string Name { get; set; }
  1. 默认的属性名不符合自己的规则的查询:例如字符串想要正值匹配,可通过特性配置

  1. [Condition("Role.RoleName", EnumCondition.Equal, EnumConditionType.And)]
  2. public string Name { get; set; }

4.排序处理

  1. 默认排序方法 DefaultOrderBy(string propName, bool isDesc = true, bool isClearReserved = true)。参数解析:属性名、降序升序、是否清掉之前的排序

  2. 默认排序方法 AddOrderBy(string propName, bool isDesc = true)。参数解析:属性名、降序升序。可添加多个,优先级按照,添加的顺序来。

  1. /// <summary>
  2. /// 设置默认的排序条件,并清空之前保留的排序条件(如果isClearReserved为true)。
  3. /// </summary>
  4. /// <param name="input">当前的QueryModel实例。</param>
  5. /// <param name="propName">要排序的属性名。</param>
  6. /// <param name="isDesc">排序方向,true为降序,false为升序。</param>
  7. /// <param name="isClearReserved">是否清空之前保留的排序条件。</param>
  8. /// <returns>返回修改后的QueryModel实例。</returns>
  9. public static QueryModel DefaultOrderBy(this QueryModel input, string propName, bool isDesc, bool isClearReserved)
  10. {
  11. // 方法实现
  12. }

  13. /// <summary>
  14. /// 向QueryModel中添加一个排序条件。
  15. /// </summary>
  16. /// <param name="input">当前的QueryModel实例。</param>
  17. /// <param name="propName">要排序的属性名。</param>
  18. /// <param name="isDesc">排序方向,true为降序,false为升序。</param>
  19. /// <returns>返回修改后的QueryModel实例。</returns>
  20. public static QueryModel AddOrderBy(this QueryModel input, string propName, bool isDesc)
  21. {
  22. // 方法实现
  23. }

  24. /// <summary>
  25. /// 向QueryModel中添加两个排序条件。
  26. /// </summary>
  27. /// <param name="input">当前的QueryModel实例。</param>
  28. /// <param name="propName">第一个要排序的属性名。</param>
  29. /// <param name="isDesc">第一个排序的方向,true为降序,false为升序。</param>
  30. /// <param name="propName2">第二个要排序的属性名。</param>
  31. /// <param name="isDesc2">第二个排序的方向,true为降序,false为升序。</param>
  32. /// <returns>返回修改后的QueryModel实例。</returns>
  33. public static QueryModel AddOrderBy(this QueryModel input, string propName, bool isDesc, string propName2, bool isDesc2)
  34. {
  35. // 方法实现
  36. }

  37. /// <summary>
  38. /// 向QueryModel中添加三个排序条件。
  39. /// </summary>
  40. /// <param name="input">当前的QueryModel实例。</param>
  41. /// <param name="propName">第一个要排序的属性名。</param>
  42. /// <param name="isDesc">第一个排序的方向,true为降序,false为升序。</param>
  43. /// <param name="propName2">第二个要排序的属性名。</param>
  44. /// <param name="isDesc2">第二个排序的方向,true为降序,false为升序。</param>
  45. /// <param name="propName3">第三个要排序的属性名。</param>
  46. /// <param name="isDesc3">第三个排序的方向,true为降序,false为升序。</param>
  47. /// <returns>返回修改后的QueryModel实例。</returns>
  48. public static QueryModel AddOrderBy(this QueryModel input, string propName, bool isDesc, string propName2, bool isDesc2, string propName3, bool isDesc3)
  49. {
  50. // 方法实现
  51. }
  52.  
  53. /// <summary>
  54. /// 向QueryModel实例中添加一组排序条件。
  55. /// </summary>
  56. /// <param name="input">当前的QueryModel实例。</param>
  57. /// <param name="orderByItems">包含排序信息的OrderByItem列表。</param>
  58. /// <returns>返回修改后的QueryModel实例(在空实现中,实际上只是返回传入的实例)。</returns>
  59. public static QueryModel AddOrderBy(this QueryModel input, List<OrderByItem> orderByItems)
  60. {
  61. // 方法实现
  62. }

  63. /// <summary>
  64. /// 向QueryModel实例中添加多个排序条件,所有条件使用相同的排序方向。
  65. /// </summary>
  66. /// <param name="input">当前的QueryModel实例。</param>
  67. /// <param name="isDesc">排序方向,true为降序,false为升序。</param>
  68. /// <param name="propNames">要排序的属性名数组。</param>
  69. /// <returns>返回修改后的QueryModel实例(在空实现中,实际上只是返回传入的实例)。</returns>
  70. public static QueryModel AddMultipleOrderBy(this QueryModel input, bool isDesc, params string[] propNames)
  71. {
  72. // 方法实现
  73. }

5.分组查询

  1. 使用特性GroupAttribute。使用分组序号,如Group(1)、如Group(1,EnumConditionType.Or)。

  1. [Group(1)]
  2. public string Name { get; set; }
  3.  
  4. [Group(1, EnumConditionType.Or)]
  5. public string UserName { get; set; }

6.时间跨度查询约束

  1. 使用特性DurationAttribute。在时间的两个属性之间中的一个打上这个特性即可。如时间跨度三个月的。

    1. /// <summary>
    2. /// 创建时间 开始
    3. /// </summary>
    4. [Duration(3, EnumTimeType.Month)]
    5. public DateTime? CreateTimeStart { get; set; }
    6. /// <summary>
    7. /// 创建时间 结束
    8. /// </summary>
    9. public DateTime? CreateTimeEnd { get; set; }

7.分页配置

  1. 没啥好说的:PageIndex 当前页 ,PageSize 显示数。

8.参数忽略

  1. 提供了特性NotQueryAttribute,在对于属性添加即可忽略构建查询。

9.构建表达式

  1. 只要类继承了QueryModel等这四个模型,即可以通过ToExpression<TSource>(),构建对于自己模型的表达式。

10.查询扩展

  1. 常规扩展,根据传入的4大模型过滤。例如

  1. /// <summary>
  2. /// 查询扩展
  3. /// </summary>
  4. public static IQueryable<T> WhereExt<T>(this IQueryable<T> source, QueryModel input)
  5. {
  6. //
  7. }
  8. /// <summary>
  9. /// 查询扩展,并排序
  10. /// </summary>
  11. public static IQueryable<T> WhereExt<T>(this IQueryable<T> source, Expression<Func<T, bool>> expression, params OrderByItem[] orderByItems)
  12. {
  13. //
  14. }
  1. 部分查询扩展,可返回传入的模型类(如果属性匹配得上的话)

  1. /// <summary>
  2. /// Select扩展方法
  3. /// </summary>
  4. /// <typeparam name="TSource"></typeparam>
  5. /// <typeparam name="TTarget"></typeparam>
  6. /// <param name="query"></param>
  7. /// <returns></returns>
  8. public static IQueryable<TTarget> Select<TSource, TTarget>(this IQueryable<TSource> query)
  9. {
  10.  
  11. }
  1. IQueryable扩展方法

  1. /// <summary>
  2. /// 根据QueryModel中的条件过滤IQueryable<T>并返回结果列表。
  3. /// </summary>
  4. /// <param name="source">待处理的IQueryable<T>。</param>
  5. /// <param name="input">包含过滤条件的QueryModel。</param>
  6. /// <returns>未经过滤的T类型列表。</returns>
  7. public static List<T> ToList<T>(this IQueryable<T> source, QueryModel input)
  8. {
  9. // 实现
  10. }
  11.  
  12. /// <summary>
  13. /// 根据FullQueryModel中的复杂条件过滤IQueryable<T>并返回结果列表。
  14. /// </summary>
  15. /// <param name="source">待处理的IQueryable<T>。</param>
  16. /// <param name="input">包含复杂过滤条件的FullQueryModel。</param>
  17. /// <returns>未经过滤的T类型列表。</returns>
  18. public static List<T> ToList<T>(this IQueryable<T> source, FullQueryModel input)
  19. {
  20. // 实现
  21. }
  22.  
  23. /// <summary>
  24. /// 根据PageModel中的分页参数对IQueryable<T>进行分页处理,并返回包含数据列表和总记录数的元组。
  25. /// </summary>
  26. /// <param name="query">待分页处理的IQueryable<T>。</param>
  27. /// <param name="input">包含分页参数的PageModel。</param>
  28. /// <returns>包含未分页数据列表和未计算总记录数的元组。</returns>
  29. public static (List<T> list, int total) ToPageList<T>(this IQueryable<T> query, PageModel input)
  30. {
  31. // 实现
  32. }
  33.  
  34. /// <summary>
  35. /// 根据FullPageModel中的分页和过滤条件对IQueryable<T>进行处理,并返回包含数据列表和总记录数的元组
  36. /// </summary>
  37. /// <param name="query">待处理的IQueryable<T>。</param>
  38. /// <param name="input">包含分页和过滤条件的FullPageModel。</param>
  39. /// <returns>包含未分页且未过滤的数据列表和未计算总记录数的元组。</returns>
  40. public static (List<T> list, int total) ToPageList<T>(this IQueryable<T> query, FullPageModel input)
  41. {
  42. // 实现
  43. }
  44.  
  45. /// <summary>
  46. /// 对IQueryable<T>进行分页处理,并返回包含数据列表和总记录数的元组。
  47. /// </summary>
  48. /// <param name="query">待分页处理的IQueryable<T>。</param>
  49. /// <param name="input">包含分页参数的PageModel。</param>
  50. /// <returns>包含未分页数据列表和未计算总记录数的元组。</returns>
  51. public static (List<T> list, int total) Page<T>(this IQueryable<T> query, PageModel input)
  52. {
  53. // 实现
  54. }
  55.  
  56. /// <summary>
  57. /// 根据FullPageModel中的分页和过滤条件对IQueryable<T>进行处理,并返回包含数据列表和总记录数的元组。
  58. /// </summary>
  59. /// <param name="query">待处理的IQueryable<T>。</param>
  60. /// <param name="input">包含分页和过滤条件的FullPageModel。</param>
  61. /// <returns>包含未分页且未过滤的数据列表和未计算总记录数的元组。</returns>
  62. public static (List<T> list, int total) Page<T>(this IQueryable<T> query, FullPageModel input)
  63. {
  64. // 实现
  65. }
  66. /// <summary>
  67. /// 根据PageModel中的分页和排序参数对IQueryable<T>进行分页和排序处理,并返回包含排序后数据列表和总记录数的元组。
  68. /// </summary>
  69. /// <param name="query">待分页和排序处理的IQueryable<T>。</param>
  70. /// <param name="input">包含分页和排序参数的PageModel。</param>
  71. /// <returns>包含未分页且未排序的数据列表和未计算总记录数的元组。</returns>
  72. public static (List<T> list, int total) OrderPageList<T>(this IQueryable<T> query, PageModel input)
  73. {
  74. // 实现
  75. }
  76.  
  77. /// <summary>
  78. /// 根据FullPageModel中的分页、排序和过滤条件对IQueryable<T>进行处理,并返回包含排序后数据列表和总记录数的元组。
  79. /// </summary>
  80. /// <param name="query">待处理的IQueryable<T>。</param>
  81. /// <param name="input">包含分页、排序和过滤条件的FullPageModel。</param>
  82. /// <returns>包含未分页、未排序且未过滤的数据列表和未计算总记录数的元组。</returns>
  83. public static (List<T> list, int total) OrderPageList<T>(this IQueryable<T> query, FullPageModel input)
  84. {
  85. // 实现
  86. }
  1. IQueryable扩展方法之排序

  1. /// <summary>
  2. /// 根据单个属性名对IQueryable<TEntity>进行排序。
  3. /// </summary>
  4. /// <param name="input">待排序的IQueryable<TEntity>。</param>
  5. /// <param name="propName">要排序的属性名。</param>
  6. /// <param name="isDesc">指示排序是否为降序。</param>
  7. /// <returns>未应用排序的IQueryable<TEntity>。</returns>
  8. public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> input, string propName, bool isDesc)
  9. {
  10. // 实现
  11. }
  12.  
  13. /// <summary>
  14. /// 根据两个属性名对IQueryable<TEntity>进行排序。
  15. /// </summary>
  16. /// <param name="input">待排序的IQueryable<TEntity>。</param>
  17. /// <param name="propName">第一个要排序的属性名。</param>
  18. /// <param name="isDesc">第一个排序是否为降序。</param>
  19. /// <param name="propName2">第二个要排序的属性名。</param>
  20. /// <param name="isDesc2">第二个排序是否为降序。</param>
  21. /// <returns>未应用排序的IQueryable<TEntity>。</returns>
  22. public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> input, string propName, bool isDesc, string propName2, bool isDesc2)
  23. {
  24. // 实现
  25. }
  26.  
  27. /// <summary>
  28. /// 根据三个属性名对IQueryable<TEntity>进行排序。
  29. /// </summary>
  30. /// <param name="input">待排序的IQueryable<TEntity>。</param>
  31. /// <param name="propName">第一个要排序的属性名。</param>
  32. /// <param name="isDesc">第一个排序是否为降序。</param>
  33. /// <param name="propName2">第二个要排序的属性名。</param>
  34. /// <param name="isDesc2">第二个排序是否为降序。</param>
  35. /// <param name="propName3">第三个要排序的属性名。</param>
  36. /// <param name="isDesc3">第三个排序是否为降序。</param>
  37. /// <returns>未应用排序的IQueryable<TEntity>。</returns>
  38. public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> input, string propName, bool isDesc, string propName2, bool isDesc2, string propName3, bool isDesc3)
  39. {
  40. // 实现
  41. }
  42.  
  43. /// <summary>
  44. /// 根据多个属性名对IQueryable<TEntity>进行排序。属性名和排序方向通过数组提供。
  45. /// </summary>
  46. /// <param name="input">待排序的IQueryable<TEntity>。</param>
  47. /// <param name="isDesc">是否所有排序都应为降序,此参数在可变参数场景下可能不被直接使用,而是作为方法重载的标识。</param>
  48. /// <param name="propNames">要排序的属性名数组。</param>
  49. /// <returns>未应用排序的IQueryable<TEntity>。</returns>
  50. public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> input, bool isDesc, params string[] propNames)
  51. {
  52. // 实现
  53. }
  54.  
  55. /// <summary>
  56. /// 根据IQueryModel中的排序信息对IQueryable<TEntity>进行排序。
  57. /// </summary>
  58. /// <param name="input">待排序的IQueryable<TEntity>。</param>
  59. /// <param name="queryModel">包含排序信息的IQueryModel。</param>
  60. /// <returns>未应用排序的IQueryable<TEntity>。</returns>
  61. public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> input, IQueryModel queryModel)
  62. {
  63. // 实现
  64. }
  65.  
  66. /// <summary>
  67. /// 根据OrderByItem数组中的排序项对IQueryable<TEntity>进行排序。
  68. /// </summary>
  69. /// <param name="input">待排序的IQueryable<TEntity>。</param>
  70. /// <param name="orderByItems">包含排序属性和排序方向的OrderByItem数组。</param>
  71. /// <returns>未应用排序的IQueryable<TEntity>。</returns>
  72. public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> input, params OrderByItem[] orderByItems)
  73. {
  74. // 实现
  75. }
  76.  
  77. /// <summary>
  78. /// 根据OrderByItem列表中的排序项对IQueryable<TEntity>进行排序。
  79. /// </summary>
  80. /// <param name="input">待排序的IQueryable<TEntity>。</param>
  81. /// <param name="orderByItems">包含排序属性和排序方向的OrderByItem列表。</param>
  82. /// <returns>未应用排序的IQueryable<TEntity>。</returns>
  83. public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> input, List<OrderByItem> orderByItems)
  84. {
  85. // 实现
  86. }

Sy.ExpressionBuilder 动态查询新体验的更多相关文章

  1. 表达式树扩展 动态生成表达式树插件 Sy.ExpressionBuilder。

    CURD中,基础查询我感觉还是很烦人的一个浪费时间的工作,我经历过远古时代的GetAll(string name,int age),这种方式写服务的时候真的是心中一万个草泥马飞过,后面逐渐的变成了传一 ...

  2. 超简单的集成表达式树查询组件,Sy.ExpressionBuilder 使用说明

    Sy.ExpressionBuilder是一套依赖于表达式树上的集成的查询组件.设计的初衷没别的,就为了少写代码,让查询业务可以变得更加模式化.目前可以从nuget 获取到该组件. 来到查询,查询实体 ...

  3. Thinkphp查询 1.查询方式 2.表达式查询 3.快捷查询 4.区间查询 5.组合查询 6.统计查询 7.动态查询 8.SQL 查询

    1.使用字符串作为条件查询 $user = M('User'); var_dump($user->where('id=1 AND user="蜡笔小新"')->sele ...

  4. ibatis动态查询条件

    ibatis的调试相对困难,出错的时候主要依据是log4生成的log文件和出错提示,这方面要能比较熟练的看懂. 下面这个配置基本上包含了最复杂的功能:分页\搜索\排序\缓存\传值Hash表\返回has ...

  5. Linq to Sql:N层应用中的查询(下) : 根据条件进行动态查询

    原文:Linq to Sql:N层应用中的查询(下) : 根据条件进行动态查询 如果允许在UI层直接访问Linq to Sql的DataContext,可以省去很多问题,譬如在处理多表join的时候, ...

  6. Mybatis动态查询语句

    MyBatis中动态SQL语句完成多条件查询 标签: mybatis动态SQL多条件查询java.sql.SQLSyntaxEr 2015-06-29 19:00 22380人阅读 评论(0) 收藏  ...

  7. 浅析Entity Framework Core2.0的日志记录与动态查询条件

    前言 Entity Framework Core 2.0更新也已经有一段时间了,园子里也有不少的文章.. 本文主要是浅析一下Entity Framework Core2.0的日志记录与动态查询条件 去 ...

  8. T-SQL动态查询(4)——动态SQL

    接上文:T-SQL动态查询(3)--静态SQL 前言: 前面说了很多关于动态查询的内容,本文将介绍使用动态SQL解决动态查询的一些方法. 为什么使用动态SQL: 在很多项目中,动态SQL被广泛使用甚至 ...

  9. T-SQL动态查询(3)——静态SQL

    接上文:T-SQL动态查询(2)--关键字查询   本文讲述关于静态SQL的一些知识和基础技巧. 简介: 什么是静态SQL?静态SQL是和动态SQL相对而言的,其实我们没必要过于纠结精确定义,只要大概 ...

  10. T-SQL动态查询(1)——简介

    起因: 由于最近工作需要及过去一直的疑问,所以决定着手研究一下动态SQL.由于离开一线开发有点年头了,很多技巧性的东西没有过多研究,作为DBA和<SQL Server性能优化与管理的艺术> ...

随机推荐

  1. Oh-My-Zsh 提示符只显示当前路径,不需要修改主题文件

    我真是服了.就这么一个简单的小问题我在网上找了一个多小时,一大堆 CSDN 文章都是抄 同一篇博客 的教程,所有的博客都要我去把 ~/.oh-my-zsh/themes/*.zsh-theme 文件里 ...

  2. 免费的Java主流jdk发行版本有哪些?

    Java的特点是百花齐放,不像c#或者go只有一家主导.oracle jdk收费了,没关系,不是只有它可用.java还有很多免费的主流的jdk发行版本,记录下来备忘. OpenJDK - 官方网站 - ...

  3. 算法金 | A - Z,115 个数据科学 机器学习 江湖黑话(全面)

    大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」 机器学习本质上和数据科学一样都是依赖概率统计,今天整整那些听起来让人头大的机器学习江湖 ...

  4. 移植 uCos-III 3.03 到 STM32F429 上

    背景 通过STM32 的学习,我们可以往更深层次的地方走,尝试系统上的一些开发. STM32: F429(StdPeriph) uCos-III : v3.04 + 3.03 有关说明: 在移植 3. ...

  5. 背包DP——完全背包

    完全背包模型与 0-1 背包类似,与 0-1 背包的区别仅在于一个物品可以选取无限次,而非仅能选取一次. 而状态转移方程于01背包区别在于可以直接从[i][j-w[i]]转移 理由是当我们这样转移时, ...

  6. SNAT,DNAT以及REDIRECT转发详解

    最近负责的其中一个项目的服务器集群出现了点网络方面的问题,在处理过程当中又涉及到了防火墙相关的知识和命令,想着有一段时间没有复习这部分内容了,于是借着此次机会复写了下顺便将本次复习的一些内容以博客的形 ...

  7. 【基础计算】ESDF栅格距离图计算并行加速版

    前言与参考 这一部分仅为路径规划源码及论文GPIR的一个小部分,但是有代码实现,第一次看的时候有些懵,所以特此记录:主要是设置好了栅格地图后,添加了障碍物后,对其的欧式距离计算和梯度计算等.原代码中为 ...

  8. Unity 中关于SubMesh的拾取问题

    问题背景 最近在开发一个功能,钻孔功能,每一层(段)都需要单独拾取,显示不同的颜色,使用不同材质 问题分析 对于这个功能,由于上述需求,很容易想到用submesh实现,但是主要问题是在于对于Subme ...

  9. RAG工程实践拦路虎之一:PDF格式解析杂谈

    背景 PDF(Portable Document Format)是一种广泛用于文档交换的文件格式,由Adobe Systems开发.它具有跨平台性.固定布局和易于打印等特点,因此在商业.学术和个人领域 ...

  10. 记一次使用python的selenium库爬取动态页面内容的经历

    安装与配置selenium 安装selenium库 pip install selenium 配置浏览器驱动(本次使用Google Chrome) 打开Chrome,在浏览器的地址栏,输入chrome ...