Browse Source

add null/not null queryable

pull/734/head
cKey 3 years ago
parent
commit
d26faa599e
  1. 8
      apps/vue/src/components/Table/src/components/AdvancedSearch.vue
  2. 6
      apps/vue/src/components/Table/src/types/advancedSearch.ts
  3. 3
      apps/vue/src/components/Table/src/types/table.ts
  4. 2
      apps/vue/src/locales/lang/en/component.ts
  5. 2
      apps/vue/src/locales/lang/zh-CN/component.ts
  6. 22
      aspnet-core/LINGYUN.MicroService.Common.sln
  7. 9
      aspnet-core/modules/dynamic-queryable/LINGYUN.Abp.Dynamic.Queryable.Application.Contracts/LINGYUN/Abp/Dynamic/Queryable/Dto/DynamicParamterDto.cs
  8. 108
      aspnet-core/modules/dynamic-queryable/LINGYUN.Abp.Dynamic.Queryable.Application/LINGYUN/Abp/Dynamic/Queryable/DynamicQueryableAppService.cs
  9. 5
      aspnet-core/modules/dynamic-queryable/LINGYUN.Linq.Dynamic.Queryable/LINGYUN.Linq.Dynamic.Queryable.csproj
  10. 10
      aspnet-core/modules/dynamic-queryable/LINGYUN.Linq.Dynamic.Queryable/LINGYUN/Linq/Dynamic/Queryable/DynamicComparison.cs
  11. 8
      aspnet-core/modules/dynamic-queryable/LINGYUN.Linq.Dynamic.Queryable/LINGYUN/Linq/Dynamic/Queryable/DynamicParamter.cs
  12. 201
      aspnet-core/modules/dynamic-queryable/LINGYUN.Linq.Dynamic.Queryable/System/Linq/Expressions/ObjectQueryableExtensions.cs
  13. 6
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application/LINGYUN/Abp/TaskManagement/BackgroundJobInfoAppService.cs
  14. 2
      aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.Configure.cs
  15. 3
      aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/appsettings.Development.json
  16. 19
      aspnet-core/tests/LINGYUN.Abp.DynamicQueryable.EntityFrameworkCore.Tests/LINGYUN.Abp.DynamicQueryable.EntityFrameworkCore.Tests.csproj
  17. 4
      aspnet-core/tests/LINGYUN.Abp.DynamicQueryable.EntityFrameworkCore.Tests/LINGYUN/Abp/DynamicQueryable/EntityFrameworkCore/AbpDynamicQueryableEntityFrameworkCoreTestBase.cs
  18. 9
      aspnet-core/tests/LINGYUN.Abp.DynamicQueryable.EntityFrameworkCore.Tests/LINGYUN/Abp/DynamicQueryable/EntityFrameworkCore/AbpDynamicQueryableEntityFrameworkCoreTestModule.cs
  19. 302
      aspnet-core/tests/LINGYUN.Abp.DynamicQueryable.EntityFrameworkCore.Tests/LINGYUN/Abp/DynamicQueryable/EntityFrameworkCore/DynamicQueryableEntityFrameworkCoreTests.cs
  20. 5
      aspnet-core/tests/LINGYUN.Abp.DynamicQueryable.EntityFrameworkCore.Tests/Usings.cs
  21. 2
      aspnet-core/tests/LINGYUN.Abp.EntityFrameworkCore.Tests/LINGYUN.Abp.EntityFrameworkCore.Tests.csproj
  22. 23
      aspnet-core/tests/LINGYUN.Abp.EntityFrameworkCore.Tests/LINGYUN/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs
  23. 24
      aspnet-core/tests/LINGYUN.Abp.EntityFrameworkCore.Tests/LINGYUN/Abp/EntityFrameworkCore/EfCoreTestDbContext.cs
  24. 25
      aspnet-core/tests/LINGYUN.Abp.EntityFrameworkCore.Tests/LINGYUN/Abp/EntityFrameworkCore/EfCoreTestEntity.cs
  25. 33
      aspnet-core/tests/LINGYUN.Abp.EntityFrameworkCore.Tests/LINGYUN/Abp/EntityFrameworkCore/EfCoreTestEntityDataSeeder.cs
  26. 18
      aspnet-core/tests/LINGYUN.Linq.Dynamic.Queryable.Tests/LINGYUN.Linq.Dynamic.Queryable.Tests.csproj
  27. 5
      aspnet-core/tests/LINGYUN.Linq.Dynamic.Queryable.Tests/LINGYUN/Linq/Dynamic/Queryable/DynamicQueryableTestBase.cs
  28. 8
      aspnet-core/tests/LINGYUN.Linq.Dynamic.Queryable.Tests/LINGYUN/Linq/Dynamic/Queryable/DynamicQueryableTestModule.cs
  29. 337
      aspnet-core/tests/LINGYUN.Linq.Dynamic.Queryable.Tests/LINGYUN/Linq/Dynamic/Queryable/DynamicQueryableTests.cs
  30. 4
      aspnet-core/tests/LINGYUN.Linq.Dynamic.Queryable.Tests/Usings.cs

8
apps/vue/src/components/Table/src/components/AdvancedSearch.vue

@ -209,6 +209,14 @@
label: t('component.table.advancedSearch.notContains'),
value: DynamicComparison.NotContains,
},
{
label: t('component.table.advancedSearch.null'),
value: DynamicComparison.Null,
},
{
label: t('component.table.advancedSearch.notNull'),
value: DynamicComparison.NotNull,
},
]);
const getAvailableParams = computed(() => {

6
apps/vue/src/components/Table/src/types/advancedSearch.ts

@ -65,7 +65,11 @@ export enum DynamicComparison {
/** 包含 */
Contains = 10,
/** 不包含 */
NotContains = 11
NotContains = 11,
/** 空 */
Null = 12,
/** 非空 */
NotNull = 12,
}
/** 动态查询字段 */

3
apps/vue/src/components/Table/src/types/table.ts

@ -1,8 +1,7 @@
import type { VNodeChild } from 'vue';
import type { PaginationProps } from './pagination';
import type { FormProps } from '/@/components/Form';
import type { ColumnProps } from 'ant-design-vue/lib/table';
import type { TableRowSelection as ITableRowSelection } from 'ant-design-vue/lib/table/interface';
import type { TableRowSelection as ITableRowSelection, ColumnProps } from 'ant-design-vue/lib/table/interface';
import type { AdvanceSearchProps } from './advancedSearch';
import { ComponentType } from './componentType';

2
apps/vue/src/locales/lang/en/component.ts

@ -94,6 +94,8 @@ export default {
notEndsWith: 'Not Ends With',
contains: 'Contains',
notContains: 'Not Contains',
null: 'Null',
notNull: 'Not Null',
}
},
time: {

2
apps/vue/src/locales/lang/zh-CN/component.ts

@ -96,6 +96,8 @@ export default {
notEndsWith: '右不包含',
contains: '包含',
notContains: '不包含',
null: '空',
notNull: '非空',
}
},
time: {

22
aspnet-core/LINGYUN.MicroService.Common.sln

@ -286,13 +286,17 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.TuiJuhe.Setting
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dynamic-queryable", "dynamic-queryable", "{3975D028-3672-4D23-BF77-B7F4A445D44E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Linq.Dynamic.Queryable", "modules\dynamic-queryable\LINGYUN.Linq.Dynamic.Queryable\LINGYUN.Linq.Dynamic.Queryable.csproj", "{5512A359-80E8-440C-B652-7C96F614DD9E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Linq.Dynamic.Queryable", "modules\dynamic-queryable\LINGYUN.Linq.Dynamic.Queryable\LINGYUN.Linq.Dynamic.Queryable.csproj", "{5512A359-80E8-440C-B652-7C96F614DD9E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Dynamic.Queryable.Application.Contracts", "modules\dynamic-queryable\LINGYUN.Abp.Dynamic.Queryable.Application.Contracts\LINGYUN.Abp.Dynamic.Queryable.Application.Contracts.csproj", "{6A23EE81-0CA7-4CA7-859D-6ADB669DF0E1}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Dynamic.Queryable.Application.Contracts", "modules\dynamic-queryable\LINGYUN.Abp.Dynamic.Queryable.Application.Contracts\LINGYUN.Abp.Dynamic.Queryable.Application.Contracts.csproj", "{6A23EE81-0CA7-4CA7-859D-6ADB669DF0E1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Dynamic.Queryable.Application", "modules\dynamic-queryable\LINGYUN.Abp.Dynamic.Queryable.Application\LINGYUN.Abp.Dynamic.Queryable.Application.csproj", "{EC7970DC-A656-46A7-9873-A730FE72B213}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Dynamic.Queryable.Application", "modules\dynamic-queryable\LINGYUN.Abp.Dynamic.Queryable.Application\LINGYUN.Abp.Dynamic.Queryable.Application.csproj", "{EC7970DC-A656-46A7-9873-A730FE72B213}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Dynamic.Queryable.HttpApi", "modules\dynamic-queryable\LINGYUN.Abp.Dynamic.Queryable.HttpApi\LINGYUN.Abp.Dynamic.Queryable.HttpApi.csproj", "{F515E8FA-449F-4D54-98A7-0F7DF1AA3C94}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Dynamic.Queryable.HttpApi", "modules\dynamic-queryable\LINGYUN.Abp.Dynamic.Queryable.HttpApi\LINGYUN.Abp.Dynamic.Queryable.HttpApi.csproj", "{F515E8FA-449F-4D54-98A7-0F7DF1AA3C94}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Linq.Dynamic.Queryable.Tests", "tests\LINGYUN.Linq.Dynamic.Queryable.Tests\LINGYUN.Linq.Dynamic.Queryable.Tests.csproj", "{E9AD81CA-D992-4F74-BD23-680CF98BE262}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.DynamicQueryable.EntityFrameworkCore.Tests", "tests\LINGYUN.Abp.DynamicQueryable.EntityFrameworkCore.Tests\LINGYUN.Abp.DynamicQueryable.EntityFrameworkCore.Tests.csproj", "{2E29FBF7-CECB-4DF9-9E02-5AFB704DDD10}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -760,6 +764,14 @@ Global
{F515E8FA-449F-4D54-98A7-0F7DF1AA3C94}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F515E8FA-449F-4D54-98A7-0F7DF1AA3C94}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F515E8FA-449F-4D54-98A7-0F7DF1AA3C94}.Release|Any CPU.Build.0 = Release|Any CPU
{E9AD81CA-D992-4F74-BD23-680CF98BE262}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E9AD81CA-D992-4F74-BD23-680CF98BE262}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E9AD81CA-D992-4F74-BD23-680CF98BE262}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E9AD81CA-D992-4F74-BD23-680CF98BE262}.Release|Any CPU.Build.0 = Release|Any CPU
{2E29FBF7-CECB-4DF9-9E02-5AFB704DDD10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2E29FBF7-CECB-4DF9-9E02-5AFB704DDD10}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2E29FBF7-CECB-4DF9-9E02-5AFB704DDD10}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2E29FBF7-CECB-4DF9-9E02-5AFB704DDD10}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -906,6 +918,8 @@ Global
{6A23EE81-0CA7-4CA7-859D-6ADB669DF0E1} = {3975D028-3672-4D23-BF77-B7F4A445D44E}
{EC7970DC-A656-46A7-9873-A730FE72B213} = {3975D028-3672-4D23-BF77-B7F4A445D44E}
{F515E8FA-449F-4D54-98A7-0F7DF1AA3C94} = {3975D028-3672-4D23-BF77-B7F4A445D44E}
{E9AD81CA-D992-4F74-BD23-680CF98BE262} = {B86C21A4-73B7-471E-B73A-B4B905EC9435}
{2E29FBF7-CECB-4DF9-9E02-5AFB704DDD10} = {B86C21A4-73B7-471E-B73A-B4B905EC9435}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {06C707C6-02C0-411A-AD3B-2D0E13787CB8}

9
aspnet-core/modules/dynamic-queryable/LINGYUN.Abp.Dynamic.Queryable.Application.Contracts/LINGYUN/Abp/Dynamic/Queryable/Dto/DynamicParamterDto.cs

@ -1,4 +1,6 @@
namespace LINGYUN.Abp.Dynamic.Queryable;
using LINGYUN.Linq.Dynamic.Queryable;
namespace LINGYUN.Abp.Dynamic.Queryable;
public class DynamicParamterDto
{
@ -6,4 +8,9 @@ public class DynamicParamterDto
public string Description { get; set; }
public string Type { get; set; }
public string JavaScriptType { get; set; }
public DynamicComparison[] AvailableComparator { get; set; }
public DynamicParamterDto()
{
AvailableComparator = new DynamicComparison[0];
}
}

108
aspnet-core/modules/dynamic-queryable/LINGYUN.Abp.Dynamic.Queryable.Application/LINGYUN/Abp/Dynamic/Queryable/DynamicQueryableAppService.cs

@ -1,4 +1,5 @@
using Microsoft.Extensions.Options;
using LINGYUN.Linq.Dynamic.Queryable;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
@ -32,13 +33,15 @@ public abstract class DynamicQueryableAppService<TEntity, TEntityDto> : Applicat
// 字段本地化描述规则
// 在本地化文件中定义 DisplayName:PropertyName
var localizedProp = L[$"DisplayName:{propertyInfo.Name}"];
var propertyTypeMap = GetPropertyTypeMap(propertyInfo.PropertyType);
dynamicParamters.Add(
new DynamicParamterDto
{
Name = propertyInfo.Name,
Type = propertyInfo.PropertyType.FullName,
Description = localizedProp.Value ?? propertyInfo.Name,
JavaScriptType = ConvertToJavaScriptType(propertyInfo.PropertyType)
JavaScriptType = propertyTypeMap.JavaScriptType,
AvailableComparator = propertyTypeMap.AvailableComparator
});
}
@ -74,10 +77,13 @@ public abstract class DynamicQueryableAppService<TEntity, TEntityDto> : Applicat
return ObjectMapper.Map<List<TEntity>, List<TEntityDto>>(entities);
}
protected virtual string ConvertToJavaScriptType(Type propertyType)
protected virtual (string JavaScriptType, DynamicComparison[] AvailableComparator) GetPropertyTypeMap(Type propertyType)
{
var isNullableType = false;
var availableComparator = new List<DynamicComparison>();
if (propertyType.IsNullableType())
{
isNullableType = true;
propertyType = propertyType.GetGenericArguments().FirstOrDefault();
}
var typeCode = Type.GetTypeCode(propertyType);
@ -94,27 +100,103 @@ public abstract class DynamicQueryableAppService<TEntity, TEntityDto> : Applicat
case TypeCode.Double:
case TypeCode.SByte:
case TypeCode.Decimal:
return "number";
// 数值类型只支持如下操作符
// 小于、小于等于、大于、大于等于、等于、不等于、空、非空
availableComparator.AddRange(new[]
{
DynamicComparison.GreaterThan,
DynamicComparison.GreaterThanOrEqual,
DynamicComparison.LessThan,
DynamicComparison.LessThanOrEqual,
DynamicComparison.Equal,
DynamicComparison.NotEqual,
});
if (isNullableType)
{
availableComparator.AddRange(new []
{
DynamicComparison.Null,
DynamicComparison.NotNull
});
}
return ("number", availableComparator.ToArray());
case TypeCode.Boolean:
return "boolean";
// 布尔类型只支持如下操作符
// 等于、不等于、空、非空
availableComparator.AddRange(new[]
{
DynamicComparison.Equal,
DynamicComparison.NotEqual,
});
if (isNullableType)
{
availableComparator.AddRange(new[]
{
DynamicComparison.Null,
DynamicComparison.NotNull
});
}
return ("boolean", availableComparator.ToArray());
case TypeCode.Char:
case TypeCode.String:
return "string";
// 字符类型支持所有操作符
return ("string", availableComparator.ToArray());
case TypeCode.DateTime:
return "Date";
// 时间类型只支持如下操作符
// 小于、小于等于、大于、大于等于、等于、不等于、空、非空
availableComparator.AddRange(new[]
{
DynamicComparison.GreaterThan,
DynamicComparison.GreaterThanOrEqual,
DynamicComparison.LessThan,
DynamicComparison.LessThanOrEqual,
DynamicComparison.Equal,
DynamicComparison.NotEqual,
});
if (isNullableType)
{
availableComparator.AddRange(new[]
{
DynamicComparison.Null,
DynamicComparison.NotNull
});
}
return ("Date", availableComparator.ToArray());
default:
case TypeCode.Object:
case TypeCode.Empty:
case TypeCode.DBNull:
if (isNullableType)
{
availableComparator.AddRange(new[]
{
DynamicComparison.Null,
DynamicComparison.NotNull
});
}
if (propertyType.IsArray)
{
return "array";
// 数组类型只支持如下操作符
// 包含、不包含、空、非空
availableComparator.AddRange(new[]
{
DynamicComparison.Contains,
DynamicComparison.NotContains,
});
return ("array", availableComparator.ToArray());
}
else
{
return "object";
// 未知对象类型只支持如下操作符
// 等于、不等于、空、非空
availableComparator.AddRange(new[]
{
DynamicComparison.Equal,
DynamicComparison.NotEqual,
});
return ("object", availableComparator.ToArray());
}
default:
case TypeCode.Empty:
case TypeCode.DBNull:
return "object";
}
}
}

5
aspnet-core/modules/dynamic-queryable/LINGYUN.Linq.Dynamic.Queryable/LINGYUN.Linq.Dynamic.Queryable.csproj

@ -8,4 +8,9 @@
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2022.1.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
</ItemGroup>
</Project>

10
aspnet-core/modules/dynamic-queryable/LINGYUN.Linq.Dynamic.Queryable/LINGYUN/Linq/Dynamic/Queryable/DynamicComparison.cs

@ -48,6 +48,14 @@ public enum DynamicComparison
/// <summary>
/// 不包含
/// </summary>
NotContains = 11
NotContains = 11,
/// <summary>
/// 空值
/// </summary>
Null = 12,
/// <summary>
/// 非空
/// </summary>
NotNull = 13
}

8
aspnet-core/modules/dynamic-queryable/LINGYUN.Linq.Dynamic.Queryable/LINGYUN/Linq/Dynamic/Queryable/DynamicParamter.cs

@ -1,7 +1,12 @@
namespace LINGYUN.Linq.Dynamic.Queryable;
using JetBrains.Annotations;
using System.ComponentModel.DataAnnotations;
namespace LINGYUN.Linq.Dynamic.Queryable;
public class DynamicParamter
{
[NotNull]
[Required]
public string Field { get; set; }
public DynamicLogic Logic { get; set; } = DynamicLogic.And;
@ -9,5 +14,6 @@ public class DynamicParamter
public DynamicComparison Comparison { get; set; } = DynamicComparison.Equal;
public object Value { get; set; }
public string Type { get; set; }
}

201
aspnet-core/modules/dynamic-queryable/LINGYUN.Linq.Dynamic.Queryable/System/Linq/Expressions/ObjectQueryableExtensions.cs

@ -34,65 +34,213 @@ public static class ObjectQueryableExtensions
{
propertyType = (leftParamter.Member as PropertyInfo)?.PropertyType ?? paramter.Value.GetType();
}
var rightParamter = Expression.Convert(Expression.Constant(paramter.Value), propertyType);
switch (paramter.Comparison)
{
case DynamicComparison.Equal:
exp = Expression.Equal(leftParamter, rightParamter);
break;
case DynamicComparison.NotEqual:
exp = Expression.NotEqual(leftParamter, rightParamter);
// For example(MySql):
// ...Other (Field <> Value)
exp = Expression.NotEqual(
leftParamter,
Expression.Convert(Expression.Constant(paramter.Value), propertyType));
break;
case DynamicComparison.LessThan:
exp = Expression.LessThan(leftParamter, rightParamter);
// For example(MySql):
// ...Other (Field < Value)
exp = Expression.LessThan(
leftParamter,
Expression.Convert(Expression.Constant(paramter.Value), propertyType));
break;
case DynamicComparison.LessThanOrEqual:
exp = Expression.LessThanOrEqual(leftParamter, rightParamter);
// For example(MySql):
// ...Other (Field <= Value)
exp = Expression.LessThanOrEqual(
leftParamter,
Expression.Convert(Expression.Constant(paramter.Value), propertyType));
break;
case DynamicComparison.GreaterThan:
exp = Expression.GreaterThan(leftParamter, rightParamter);
// For example(MySql):
// ...Other (Field > Value)
exp = Expression.GreaterThan(
leftParamter,
Expression.Convert(Expression.Constant(paramter.Value), propertyType));
break;
case DynamicComparison.GreaterThanOrEqual:
exp = Expression.GreaterThanOrEqual(leftParamter, rightParamter);
// For example(MySql):
// ...Other (Field >= Value)
exp = Expression.GreaterThanOrEqual(
leftParamter,
Expression.Convert(Expression.Constant(paramter.Value), propertyType));
break;
case DynamicComparison.StartsWith:
// For example(MySql):
// ...Other And Field LIKE 'Value%'
exp = Expression.Call(
leftParamter,
typeof(string).GetMethod(nameof(String.StartsWith), new[] { typeof(string) }),
rightParamter);
Expression.Convert(Expression.Constant(paramter.Value), propertyType));
// TODO: 单元测试通过
// For example(MySql):
// ...Other ((Field IS NOT NULL) AND (Field LIKE 'Value%'))
//var startsWithNotNullExp = Expression.Not(
// Expression.Equal(leftParamter,
// Expression.Convert(
// Expression.Constant(null), propertyType)));
//var startsWithExp = Expression.Call(
// leftParamter,
// typeof(string).GetMethod(nameof(String.StartsWith), new[] { typeof(string) }),
// rightParamter);
//exp = Expression.AndAlso(startsWithNotNullExp, startsWithExp);
break;
case DynamicComparison.NotStartsWith:
// For example(MySql):
// ...Other NOT Field LIKE 'Value%'
exp = Expression.Not(
Expression.Call(
leftParamter,
typeof(string).GetMethod(nameof(String.StartsWith), new[] { typeof(string) }),
rightParamter));
Expression.Convert(Expression.Constant(paramter.Value), propertyType)));
// TODO: 单元测试通过
// For example(MySql):
// ...Other ((Field IS NULL) OR NOT (Field LIKE 'Value%'))
//var notStartsWithNullExp = Expression.Equal(leftParamter,
// Expression.Convert(
// Expression.Constant(null), propertyType));
//var notStartsWithExp = Expression.Not(
// Expression.Call(
// leftParamter,
// typeof(string).GetMethod(nameof(String.StartsWith), new[] { typeof(string) }),
// rightParamter));
//exp = Expression.OrElse(notStartsWithNullExp, notStartsWithExp);
break;
case DynamicComparison.EndsWith:
// For example(MySql):
// ...Other AND Field LIKE '%Value'
exp = Expression.Call(
leftParamter,
typeof(string).GetMethod(nameof(String.EndsWith), new[] { typeof(string) }),
rightParamter);
Expression.Convert(Expression.Constant(paramter.Value), propertyType));
// TODO: 单元测试通过
// For example(MySql):
// ...Other ((Field IS NOT NULL) AND (Field LIKE '%Value'))
//var endsWithNotNullExp = Expression.Not(
// Expression.Equal(leftParamter,
// Expression.Convert(
// Expression.Constant(null), propertyType)));
//var endsWithExp = Expression.Call(
// leftParamter,
// typeof(string).GetMethod(nameof(String.EndsWith), new[] { typeof(string) }),
// rightParamter);
//exp = Expression.AndAlso(endsWithNotNullExp, endsWithExp);
break;
case DynamicComparison.NotEndsWith:
// For example(MySql):
// ...Other NOT (Field LIKE '%Value')
exp = Expression.Not(
Expression.Call(
leftParamter,
typeof(string).GetMethod(nameof(String.EndsWith), new[] { typeof(string) }),
rightParamter));
Expression.Convert(Expression.Constant(paramter.Value), propertyType)));
// TODO: 单元测试通过
// For example(MySql):
// ...Other ((Field IS NULL) OR NOT (Field LIKE '%Value'))
//var notEndsWithNullExp = Expression.Equal(leftParamter,
// Expression.Convert(
// Expression.Constant(null), propertyType));
//var notEndsWithExp = Expression.Not(
// Expression.Call(
// leftParamter,
// typeof(string).GetMethod(nameof(String.EndsWith), new[] { typeof(string) }),
// rightParamter));
//exp = Expression.OrElse(notEndsWithNullExp, notEndsWithExp);
break;
case DynamicComparison.Contains:
// For example(MySql):
// ...Other AND (Field LIKE '%Value%')
exp = Expression.Call(
leftParamter,
typeof(string).GetMethod(nameof(String.Contains), new[] { typeof(string) }),
rightParamter);
Expression.Convert(Expression.Constant(paramter.Value), propertyType));
// TODO: 单元测试通过
// For example(MySql):
// ...Other ((Field IS NOT NULL) AND (Field LIKE '%Value%'))
//var containsNotNullExp = Expression.Not(
// Expression.Equal(leftParamter,
// Expression.Convert(
// Expression.Constant(null), propertyType)));
//var containsExp = Expression.Call(
// leftParamter,
// typeof(string).GetMethod(nameof(String.Contains), new[] { typeof(string) }),
// rightParamter);
//exp = Expression.AndAlso(containsNotNullExp, containsExp);
break;
case DynamicComparison.NotContains:
// For example(MySql):
// ...Other AND (Field NOT LIKE '%Value%')
exp = Expression.Not(
Expression.Call(
leftParamter,
typeof(string).GetMethod(nameof(String.Contains), new[] { typeof(string) }),
rightParamter));
Expression.Call(
leftParamter,
typeof(string).GetMethod(nameof(String.Contains), new[] { typeof(string) }),
Expression.Convert(Expression.Constant(paramter.Value), propertyType)));
// TODO: 单元测试通过
// For example(MySql):
// ...Other ((Field IS NULL) OR (Field NOT LIKE '%Value%'))
//var notContainsNullExp = Expression.Equal(leftParamter,
// Expression.Convert(
// Expression.Constant(null), propertyType));
//var notContainsExp = Expression.Not(
// Expression.Call(
// leftParamter,
// typeof(string).GetMethod(nameof(String.Contains), new[] { typeof(string) }),
// rightParamter));
//exp = Expression.OrElse(notContainsNullExp, notContainsExp);
break;
case DynamicComparison.Null:
// For example(MySql):
// ...Other (Field IS NULL)
// 非空字段设定为比对默认值
exp = Expression.Equal(leftParamter,
Expression.Convert(
Expression.Constant(GetDefaultValue(propertyType)), propertyType));
break;
case DynamicComparison.NotNull:
// For example(MySql):
// ...Other (Field IS NOT NULL)
exp = Expression.NotEqual(leftParamter,
Expression.Convert(
Expression.Constant(GetDefaultValue(propertyType)), propertyType));
break;
default:
case DynamicComparison.Equal:
// For example(MySql):
// ...Other (Field = Value)
exp = Expression.Equal(
leftParamter,
Expression.Convert(Expression.Constant(paramter.Value), propertyType));
break;
}
expressions.Push(exp);
@ -104,16 +252,27 @@ public static class ObjectQueryableExtensions
switch (paramter.Logic)
{
case DynamicLogic.And:
expressions.Push(Expression.AndAlso(exp1, exp2));
break;
case DynamicLogic.Or:
expressions.Push(Expression.Or(exp1, exp2));
break;
default:
case DynamicLogic.And:
expressions.Push(Expression.AndAlso(exp1, exp2));
break;
}
}
}
return Expression.Lambda<T>(expressions.Pop(), condition.Parameters.ToArray());
}
private static object GetDefaultValue(Type type)
{
// TODO: 非空字段此处返回默认值
if (type.IsNullableType())
{
return null;
}
return type.IsValueType ? Activator.CreateInstance(type) : null;
}
}

6
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application/LINGYUN/Abp/TaskManagement/BackgroundJobInfoAppService.cs

@ -374,9 +374,13 @@ public class BackgroundJobInfoAppService : DynamicQueryableAppService<Background
{
var queryable = await BackgroundJobInfoRepository.GetQueryableAsync();
var sorting = !pageRequest.Sorting.IsNullOrWhiteSpace()
? pageRequest.Sorting
: $"{nameof(BackgroundJobInfo.CreationTime)} DESC";
return await AsyncExecuter.ToListAsync(
queryable.Where(condition)
.PageBy(pageRequest.SkipCount, pageRequest.MaxResultCount)
.OrderBy(pageRequest.Sorting ?? $"{nameof(BackgroundJobInfo.CreationTime)} DESC"));
.OrderBy(sorting));
}
}

2
aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.Configure.cs

@ -294,7 +294,7 @@ public partial class TaskManagementHttpApiHostModule
if (isDevelopment)
{
// services.AddAlwaysAllowAuthorization();
services.AddAlwaysAllowAuthorization();
}
if (!isDevelopment)

3
aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/appsettings.Development.json

@ -1,6 +1,6 @@
{
"AgileConfig": {
"IsEnabled": true,
"IsEnabled": false,
"env": "DEV",
"appId": "LINGYUN.Abp.TaskManagement",
"secret": "1q2w3E*",
@ -115,6 +115,7 @@
"Override": {
"System": "Warning",
"Microsoft": "Warning",
"Microsoft.EntityFrameworkCore": "Debug",
"DotNetCore": "Warning"
}
},

19
aspnet-core/tests/LINGYUN.Abp.DynamicQueryable.EntityFrameworkCore.Tests/LINGYUN.Abp.DynamicQueryable.EntityFrameworkCore.Tests.csproj

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace />
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\modules\dynamic-queryable\LINGYUN.Linq.Dynamic.Queryable\LINGYUN.Linq.Dynamic.Queryable.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.EntityFrameworkCore.Tests\LINGYUN.Abp.EntityFrameworkCore.Tests.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.TestBase\LINGYUN.Abp.TestsBase.csproj" />
</ItemGroup>
</Project>

4
aspnet-core/tests/LINGYUN.Abp.DynamicQueryable.EntityFrameworkCore.Tests/LINGYUN/Abp/DynamicQueryable/EntityFrameworkCore/AbpDynamicQueryableEntityFrameworkCoreTestBase.cs

@ -0,0 +1,4 @@
namespace LINGYUN.Abp.DynamicQueryable.EntityFrameworkCore;
public abstract class AbpDynamicQueryableEntityFrameworkCoreTestBase : AbpTestsBase<AbpDynamicQueryableEntityFrameworkCoreTestModule>
{
}

9
aspnet-core/tests/LINGYUN.Abp.DynamicQueryable.EntityFrameworkCore.Tests/LINGYUN/Abp/DynamicQueryable/EntityFrameworkCore/AbpDynamicQueryableEntityFrameworkCoreTestModule.cs

@ -0,0 +1,9 @@
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.DynamicQueryable.EntityFrameworkCore;
[DependsOn(typeof(AbpEntityFrameworkCoreTestModule))]
public class AbpDynamicQueryableEntityFrameworkCoreTestModule : AbpModule
{
}

302
aspnet-core/tests/LINGYUN.Abp.DynamicQueryable.EntityFrameworkCore.Tests/LINGYUN/Abp/DynamicQueryable/EntityFrameworkCore/DynamicQueryableEntityFrameworkCoreTests.cs

@ -0,0 +1,302 @@
using LINGYUN.Abp.EntityFrameworkCore;
using System;
using System.Linq;
using System.Linq.Expressions;
using ExecDynamicQueryable = LINGYUN.Linq.Dynamic.Queryable.DynamicQueryable;
namespace LINGYUN.Abp.DynamicQueryable.EntityFrameworkCore;
public class DynamicQueryableEntityFrameworkCoreTests : AbpDynamicQueryableEntityFrameworkCoreTestBase
{
[Fact]
public void Should_Null()
{
using var dbContext = GetRequiredService<EfCoreTestDbContext>();
Expression<Func<EfCoreTestEntity, bool>> exp = (_) => true;
var dynamicQueryable = new ExecDynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.Null,
Field = nameof(EfCoreTestEntity.PropString),
Logic = DynamicLogic.And
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = dbContext.TestEntities.Local.Where(exp.Compile()).ToList();
result.Count.ShouldBe(2);
}
[Fact]
public void Should_Not_Null()
{
using var dbContext = GetRequiredService<EfCoreTestDbContext>();
Expression<Func<EfCoreTestEntity, bool>> exp = (_) => true;
var dynamicQueryable = new ExecDynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.NotNull,
Field = nameof(EfCoreTestEntity.PropString),
Logic = DynamicLogic.And
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = dbContext.TestEntities.Local.Where(exp.Compile()).ToList();
result.Count.ShouldBe(2);
}
[Fact]
public void Should_Equal()
{
using var dbContext = GetRequiredService<EfCoreTestDbContext>();
Expression<Func<EfCoreTestEntity, bool>> exp = (_) => true;
var dynamicQueryable = new ExecDynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.Equal,
Field = nameof(EfCoreTestEntity.PropInt32),
Logic = DynamicLogic.And,
Value = 2048
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = dbContext.TestEntities.Local.Where(exp.Compile()).ToList();
result.Count.ShouldBe(1);
}
[Fact]
public void Should_Not_Equal()
{
using var dbContext = GetRequiredService<EfCoreTestDbContext>();
Expression<Func<EfCoreTestEntity, bool>> exp = (_) => true;
var dynamicQueryable = new ExecDynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.NotEqual,
Field = nameof(EfCoreTestEntity.PropInt32),
Logic = DynamicLogic.And,
Value = null
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = dbContext.TestEntities.Local.Where(exp.Compile()).ToList();
result.Count.ShouldBe(2);
}
[Fact]
public void Should_Less_Than()
{
using var dbContext = GetRequiredService<EfCoreTestDbContext>();
Expression<Func<EfCoreTestEntity, bool>> exp = (_) => true;
var dynamicQueryable = new ExecDynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.LessThan,
Field = nameof(EfCoreTestEntity.PropInt32),
Logic = DynamicLogic.And,
Value = 2048
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = dbContext.TestEntities.Local.Where(exp.Compile()).ToList();
result.Count.ShouldBe(1);
}
[Fact]
public void Should_Less_Than_Or_Equal()
{
using var dbContext = GetRequiredService<EfCoreTestDbContext>();
Expression<Func<EfCoreTestEntity, bool>> exp = (_) => true;
var dynamicQueryable = new ExecDynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.LessThanOrEqual,
Field = nameof(EfCoreTestEntity.PropInt32),
Logic = DynamicLogic.And,
Value = 2048
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = dbContext.TestEntities.Local.Where(exp.Compile()).ToList();
result.Count.ShouldBe(2);
}
[Fact]
public void Should_Greater_Than()
{
using var dbContext = GetRequiredService<EfCoreTestDbContext>();
Expression<Func<EfCoreTestEntity, bool>> exp = (_) => true;
var dynamicQueryable = new ExecDynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.GreaterThan,
Field = nameof(EfCoreTestEntity.PropInt64),
Logic = DynamicLogic.And,
Value = 1024L
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = dbContext.TestEntities.Local.Where(exp.Compile()).ToList();
result.Count.ShouldBe(2);
}
[Fact]
public void Should_Greater_Than_Or_Equal()
{
using var dbContext = GetRequiredService<EfCoreTestDbContext>();
Expression<Func<EfCoreTestEntity, bool>> exp = (_) => true;
var dynamicQueryable = new ExecDynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.GreaterThanOrEqual,
Field = nameof(EfCoreTestEntity.PropInt64),
Logic = DynamicLogic.And,
Value = 1024L
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = dbContext.TestEntities.Local.Where(exp.Compile()).ToList();
result.Count.ShouldBe(3);
}
[Fact]
public void Should_Starts_With()
{
using var dbContext = GetRequiredService<EfCoreTestDbContext>();
Expression<Func<EfCoreTestEntity, bool>> exp = (_) => true;
var dynamicQueryable = new ExecDynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.StartsWith,
Field = nameof(EfCoreTestEntity.PropString),
Logic = DynamicLogic.And,
Value = "1"
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = dbContext.TestEntities.Local.Where(exp.Compile()).ToList();
result.Count.ShouldBe(1);
}
[Fact]
public void Should_Not_Starts_With()
{
using var dbContext = GetRequiredService<EfCoreTestDbContext>();
Expression<Func<EfCoreTestEntity, bool>> exp = (_) => true;
var dynamicQueryable = new ExecDynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.NotStartsWith,
Field = nameof(EfCoreTestEntity.PropString),
Logic = DynamicLogic.And,
Value = "1"
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = dbContext.TestEntities.Local.Where(exp.Compile()).ToList();
result.Count.ShouldBe(3);
}
[Fact]
public void Should_Ends_With()
{
using var dbContext = GetRequiredService<EfCoreTestDbContext>();
Expression<Func<EfCoreTestEntity, bool>> exp = (_) => true;
var dynamicQueryable = new ExecDynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.EndsWith,
Field = nameof(EfCoreTestEntity.PropString),
Logic = DynamicLogic.And,
Value = "1"
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = dbContext.TestEntities.Local.Where(exp.Compile()).ToList();
result.Count.ShouldBe(1);
}
[Fact]
public void Should_Not_Ends_With()
{
using var dbContext = GetRequiredService<EfCoreTestDbContext>();
Expression<Func<EfCoreTestEntity, bool>> exp = (_) => true;
var dynamicQueryable = new ExecDynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.NotEndsWith,
Field = nameof(EfCoreTestEntity.PropString),
Logic = DynamicLogic.And,
Value = "1"
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = dbContext.TestEntities.Local.Where(exp.Compile()).ToList();
result.Count.ShouldBe(3);
}
[Fact]
public void Should_Contains()
{
using var dbContext = GetRequiredService<EfCoreTestDbContext>();
Expression<Func<EfCoreTestEntity, bool>> exp = (_) => true;
var dynamicQueryable = new ExecDynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.Contains,
Field = nameof(EfCoreTestEntity.PropString),
Logic = DynamicLogic.And,
Value = "22"
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = dbContext.TestEntities.Local.Where(exp.Compile()).ToList();
result.Count.ShouldBe(2);
}
[Fact]
public void Should_Not_Contains()
{
using var dbContext = GetRequiredService<EfCoreTestDbContext>();
Expression<Func<EfCoreTestEntity, bool>> exp = (_) => true;
var dynamicQueryable = new ExecDynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.NotContains,
Field = nameof(EfCoreTestEntity.PropString),
Logic = DynamicLogic.And,
Value = "23"
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = dbContext.TestEntities.Local.Where(exp.Compile()).ToList();
result.Count.ShouldBe(3);
}
}

5
aspnet-core/tests/LINGYUN.Abp.DynamicQueryable.EntityFrameworkCore.Tests/Usings.cs

@ -0,0 +1,5 @@
global using Xunit;
global using Shouldly;
global using LINGYUN.Abp.EntityFrameworkCore.Tests;
global using LINGYUN.Abp.Tests;
global using LINGYUN.Linq.Dynamic.Queryable;

2
aspnet-core/tests/LINGYUN.Abp.EntityFrameworkCore.Tests/LINGYUN.Abp.EntityFrameworkCore.Tests.csproj

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>

23
aspnet-core/tests/LINGYUN.Abp.EntityFrameworkCore.Tests/LINGYUN/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs

@ -4,6 +4,7 @@ using Microsoft.Extensions.DependencyInjection;
using System;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Modularity;
using Volo.Abp.Threading;
using Volo.Abp.Uow;
namespace LINGYUN.Abp.EntityFrameworkCore.Tests
@ -13,9 +14,22 @@ namespace LINGYUN.Abp.EntityFrameworkCore.Tests
)]
public class AbpEntityFrameworkCoreTestModule : AbpModule
{
//private string _testDbFile = "./abp-ef-test-db.db";
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddEntityFrameworkInMemoryDatabase();
//var connectionString = $"Data Source={_testDbFile}";
//var sqliteConnection = CreateDatabaseAndGetConnection(connectionString);
var memoryDbName = Guid.NewGuid().ToString();
var dbConetxt = CreateDatabaseAndGetDbContext(memoryDbName);
AsyncHelper.RunSync(async () =>
await new EfCoreTestEntityDataSeeder(dbConetxt).SeedAsync());
context.Services.AddSingleton(dbConetxt);
var databaseName = Guid.NewGuid().ToString();
@ -27,7 +41,7 @@ namespace LINGYUN.Abp.EntityFrameworkCore.Tests
abpDbContextConfigurationContext.DbContextOptions.EnableSensitiveDataLogging();
abpDbContextConfigurationContext.DbContextOptions.UseEFCoreLogger();
abpDbContextConfigurationContext.DbContextOptions.UseInMemoryDatabase(databaseName);
abpDbContextConfigurationContext.DbContextOptions.UseInMemoryDatabase(memoryDbName);
});
});
@ -36,5 +50,12 @@ namespace LINGYUN.Abp.EntityFrameworkCore.Tests
options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; //EF in-memory database does not support transactions
});
}
private EfCoreTestDbContext CreateDatabaseAndGetDbContext(string dbName)
{
return new EfCoreTestDbContext(
new DbContextOptionsBuilder<EfCoreTestDbContext>().UseInMemoryDatabase(dbName).Options
);
}
}
}

24
aspnet-core/tests/LINGYUN.Abp.EntityFrameworkCore.Tests/LINGYUN/Abp/EntityFrameworkCore/EfCoreTestDbContext.cs

@ -0,0 +1,24 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.Modeling;
namespace LINGYUN.Abp.EntityFrameworkCore;
public class EfCoreTestDbContext : AbpDbContext<EfCoreTestDbContext>
{
public virtual DbSet<EfCoreTestEntity> TestEntities { get; set; }
public EfCoreTestDbContext(
DbContextOptions<EfCoreTestDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<EfCoreTestEntity>(b =>
{
b.ConfigureByConvention();
});
}
}

25
aspnet-core/tests/LINGYUN.Abp.EntityFrameworkCore.Tests/LINGYUN/Abp/EntityFrameworkCore/EfCoreTestEntity.cs

@ -0,0 +1,25 @@
using System;
using Volo.Abp.Domain.Entities;
namespace LINGYUN.Abp.EntityFrameworkCore;
public class EfCoreTestEntity : Entity<Guid>
{
public virtual string PropString { get; set; }
public virtual int? PropInt32 { get; set; }
public virtual long? PropInt64 { get; set; }
public virtual DateTime? DateTime { get; set; }
public EfCoreTestEntity(
Guid id,
string propString = null,
int? propInt32 = null,
long? propInt64 = null,
DateTime? dateTime = null)
: base(id)
{
PropString = propString;
PropInt32 = propInt32;
PropInt64 = propInt64;
DateTime = dateTime;
}
}

33
aspnet-core/tests/LINGYUN.Abp.EntityFrameworkCore.Tests/LINGYUN/Abp/EntityFrameworkCore/EfCoreTestEntityDataSeeder.cs

@ -0,0 +1,33 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage;
using System;
using System.Threading.Tasks;
namespace LINGYUN.Abp.EntityFrameworkCore;
public class EfCoreTestEntityDataSeeder
{
private readonly EfCoreTestDbContext _dbContext;
public EfCoreTestEntityDataSeeder(
EfCoreTestDbContext dbContext)
{
_dbContext = dbContext;
}
public async virtual Task SeedAsync()
{
//_dbContext.GetService<IRelationalDatabaseCreator>().CreateTables();
await _dbContext.TestEntities.AddAsync(
new EfCoreTestEntity(Guid.NewGuid(), "1223", 1024, 1024L, new DateTime(2021, 10, 1, 0, 0, 0)));
await _dbContext.TestEntities.AddAsync(
new EfCoreTestEntity(Guid.NewGuid(), null, 2048, 2048L, new DateTime(2022, 10, 1, 12, 0, 0)));
await _dbContext.TestEntities.AddAsync(
new EfCoreTestEntity(Guid.NewGuid(), "3221", null, 4096L, null));
await _dbContext.TestEntities.AddAsync(
new EfCoreTestEntity(Guid.NewGuid(), null, null, null, new DateTime(2022, 1, 1, 12, 0, 0)));
}
}

18
aspnet-core/tests/LINGYUN.Linq.Dynamic.Queryable.Tests/LINGYUN.Linq.Dynamic.Queryable.Tests.csproj

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace />
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\modules\dynamic-queryable\LINGYUN.Linq.Dynamic.Queryable\LINGYUN.Linq.Dynamic.Queryable.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.TestBase\LINGYUN.Abp.TestsBase.csproj" />
</ItemGroup>
</Project>

5
aspnet-core/tests/LINGYUN.Linq.Dynamic.Queryable.Tests/LINGYUN/Linq/Dynamic/Queryable/DynamicQueryableTestBase.cs

@ -0,0 +1,5 @@
namespace LINGYUN.Linq.Dynamic.Queryable;
public abstract class DynamicQueryableTestBase : AbpTestsBase<DynamicQueryableTestModule>
{
}

8
aspnet-core/tests/LINGYUN.Linq.Dynamic.Queryable.Tests/LINGYUN/Linq/Dynamic/Queryable/DynamicQueryableTestModule.cs

@ -0,0 +1,8 @@
using Volo.Abp.Modularity;
namespace LINGYUN.Linq.Dynamic.Queryable;
[DependsOn(typeof(AbpTestsBaseModule))]
public class DynamicQueryableTestModule : AbpModule
{
}

337
aspnet-core/tests/LINGYUN.Linq.Dynamic.Queryable.Tests/LINGYUN/Linq/Dynamic/Queryable/DynamicQueryableTests.cs

@ -0,0 +1,337 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace LINGYUN.Linq.Dynamic.Queryable;
public class LinqTestClass
{
public string StringNull { get; set; }
public string StringRequired { get; set; }
public long? Int64Null { get; set; }
public long Int64Required { get; set; }
public DateTime? DateTimeNull { get; set; }
public DateTime DateTimeRequired { get; set; }
public DateOnly? DateOnlyNull { get; set; }
public DateOnly DateOnlyRequired { get; set; }
public TimeOnly? TimeOnlyNull { get; set; }
public TimeOnly TimeOnlyRequired { get; set; }
}
public class DynamicQueryableTests : DynamicQueryableTestBase
{
private readonly static List<LinqTestClass> _testClasses;
static DynamicQueryableTests()
{
_testClasses = new List<LinqTestClass>
{
new LinqTestClass
{
StringNull = null,
StringRequired = "3211",
DateOnlyNull = new DateOnly(2022, 1, 1),
DateOnlyRequired = new DateOnly(2022, 10, 1),
TimeOnlyNull = null,
TimeOnlyRequired = new TimeOnly(12, 0, 0),
DateTimeNull = new DateTime(2021, 1, 1, 0, 0, 0),
DateTimeRequired = new DateTime(2022, 10, 1, 12, 0, 0),
Int64Null = null,
Int64Required = 1024L
},
new LinqTestClass
{
StringNull = "not null",
StringRequired = "1123",
DateOnlyNull = null,
DateOnlyRequired = new DateOnly(2021, 10, 1),
TimeOnlyNull = new TimeOnly(0, 0, 0),
TimeOnlyRequired = new TimeOnly(1, 0, 0),
DateTimeNull = null,
DateTimeRequired = new DateTime(2021, 1, 1, 0, 0, 0),
Int64Null = null,
Int64Required = 2048L
},
};
}
[Fact]
public void Should_Null()
{
Expression<Func<LinqTestClass, bool>> exp = (_) => true;
var dynamicQueryable = new DynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.Null,
Field = nameof(LinqTestClass.Int64Null),
Logic = DynamicLogic.And
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = _testClasses.Where(exp.Compile()).ToList();
result.Count.ShouldBe(2);
}
[Fact]
public void Should_Not_Null()
{
Expression<Func<LinqTestClass, bool>> exp = (_) => true;
var dynamicQueryable = new DynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.NotNull,
Field = nameof(LinqTestClass.StringNull),
Logic = DynamicLogic.And
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = _testClasses.Where(exp.Compile()).ToList();
result.Count.ShouldBe(1);
}
[Fact]
public void Should_Equal()
{
Expression<Func<LinqTestClass, bool>> exp = (_) => true;
var dynamicQueryable = new DynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.Equal,
Field = nameof(LinqTestClass.StringRequired),
Logic = DynamicLogic.And,
Value = "1123"
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = _testClasses.Where(exp.Compile()).ToList();
result.Count.ShouldBe(1);
}
[Fact]
public void Should_Not_Equal()
{
Expression<Func<LinqTestClass, bool>> exp = (_) => true;
var dynamicQueryable = new DynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.NotEqual,
Field = nameof(LinqTestClass.StringRequired),
Logic = DynamicLogic.And,
Value = "1123"
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = _testClasses.Where(exp.Compile()).ToList();
result.Count.ShouldBe(1);
}
[Fact]
public void Should_Less_Than()
{
Expression<Func<LinqTestClass, bool>> exp = (_) => true;
var dynamicQueryable = new DynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.LessThan,
Field = nameof(LinqTestClass.Int64Required),
Logic = DynamicLogic.And,
Value = 2048L
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = _testClasses.Where(exp.Compile()).ToList();
result.Count.ShouldBe(1);
}
[Fact]
public void Should_Less_Than_Or_Equal()
{
Expression<Func<LinqTestClass, bool>> exp = (_) => true;
var dynamicQueryable = new DynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.LessThanOrEqual,
Field = nameof(LinqTestClass.Int64Required),
Logic = DynamicLogic.And,
Value = 2048L
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = _testClasses.Where(exp.Compile()).ToList();
result.Count.ShouldBe(2);
}
[Fact]
public void Should_Greater_Than()
{
Expression<Func<LinqTestClass, bool>> exp = (_) => true;
var dynamicQueryable = new DynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.GreaterThan,
Field = nameof(LinqTestClass.Int64Null),
Logic = DynamicLogic.And,
Value = 1024L
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = _testClasses.Where(exp.Compile()).ToList();
result.Count.ShouldBe(0);
}
[Fact]
public void Should_Greater_Than_Or_Equal()
{
Expression<Func<LinqTestClass, bool>> exp = (_) => true;
var dynamicQueryable = new DynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.GreaterThanOrEqual,
Field = nameof(LinqTestClass.Int64Required),
Logic = DynamicLogic.And,
Value = 1024L
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = _testClasses.Where(exp.Compile()).ToList();
result.Count.ShouldBe(2);
}
[Fact]
public void Should_Starts_With()
{
Expression<Func<LinqTestClass, bool>> exp = (_) => true;
var dynamicQueryable = new DynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.StartsWith,
Field = nameof(LinqTestClass.StringNull),
Logic = DynamicLogic.And,
Value = "not"
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = _testClasses.Where(exp.Compile()).ToList();
result.Count.ShouldBe(1);
}
[Fact]
public void Should_Not_Starts_With()
{
Expression<Func<LinqTestClass, bool>> exp = (_) => true;
var dynamicQueryable = new DynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.NotStartsWith,
Field = nameof(LinqTestClass.StringNull),
Logic = DynamicLogic.And,
Value = "not"
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = _testClasses.Where(exp.Compile()).ToList();
result.Count.ShouldBe(1);
}
[Fact]
public void Should_Ends_With()
{
Expression<Func<LinqTestClass, bool>> exp = (_) => true;
var dynamicQueryable = new DynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.EndsWith,
Field = nameof(LinqTestClass.StringNull),
Logic = DynamicLogic.And,
Value = "null"
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = _testClasses.Where(exp.Compile()).ToList();
result.Count.ShouldBe(1);
}
[Fact]
public void Should_Not_Ends_With()
{
Expression<Func<LinqTestClass, bool>> exp = (_) => true;
var dynamicQueryable = new DynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.NotEndsWith,
Field = nameof(LinqTestClass.StringNull),
Logic = DynamicLogic.And,
Value = "null"
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = _testClasses.Where(exp.Compile()).ToList();
result.Count.ShouldBe(1);
}
[Fact]
public void Should_Contains()
{
Expression<Func<LinqTestClass, bool>> exp = (_) => true;
var dynamicQueryable = new DynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.Contains,
Field = nameof(LinqTestClass.StringNull),
Logic = DynamicLogic.And,
Value = "null"
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = _testClasses.Where(exp.Compile()).ToList();
result.Count.ShouldBe(1);
}
[Fact]
public void Should_Not_Contains()
{
Expression<Func<LinqTestClass, bool>> exp = (_) => true;
var dynamicQueryable = new DynamicQueryable();
dynamicQueryable.Paramters.Add(new DynamicParamter
{
Comparison = DynamicComparison.NotContains,
Field = nameof(LinqTestClass.StringNull),
Logic = DynamicLogic.And,
Value = "test"
});
exp = exp.DynamicQuery(dynamicQueryable);
var result = _testClasses.Where(exp.Compile()).ToList();
result.Count.ShouldBe(2);
}
}

4
aspnet-core/tests/LINGYUN.Linq.Dynamic.Queryable.Tests/Usings.cs

@ -0,0 +1,4 @@
global using Xunit;
global using Shouldly;
global using LINGYUN.Abp.Tests;
global using LINGYUN.Linq.Dynamic.Queryable;
Loading…
Cancel
Save