├── .gitattributes
├── .gitignore
├── AA.AspNetCore
├── AA.AspNetCore.csproj
├── Extensions
│ └── ServiceCollectionExtensions.cs
└── Results
│ └── Result.cs
├── AA.AutoMapper
├── AA.AutoMapper.csproj
├── AutoMapperConfiguration.cs
├── AutoMapperObjectMapper.cs
└── IMapperConfiguration.cs
├── AA.Dapper
├── AA.Dapper.csproj
├── Advanced
│ ├── Attributes
│ │ ├── DataSourceAttribute.cs
│ │ └── TransactionAttribute.cs
│ ├── DbContextHolder.cs
│ ├── DbDataSource.cs
│ ├── IDbDatasource.cs
│ └── Interceptor
│ │ ├── DataSourceInterceptor.cs
│ │ └── TransactionInterceptor.cs
├── Configuration
│ ├── IMapConfiguration.cs
│ └── MapConfiguration.cs
├── ConfigurationBasedDbMetadataFactory.cs
├── DapperContext.cs
├── DbMetadata.cs
├── DbMetadataFactory.cs
├── DbProvider.cs
├── Dommel
│ ├── Any.cs
│ ├── AutoMultiMap.cs
│ ├── Cache.cs
│ ├── ColumnPropertyInfo.cs
│ ├── Count.cs
│ ├── DefaultColumnNameResolver.cs
│ ├── DefaultForeignKeyPropertyResolver.cs
│ ├── DefaultKeyPropertyResolver.cs
│ ├── DefaultPropertyResolver.cs
│ ├── DefaultTableNameResolver.cs
│ ├── Delete.cs
│ ├── DommelMapper.cs
│ ├── ForeignKeyRelation.cs
│ ├── From.cs
│ ├── Get.cs
│ ├── IColumnNameResolver.cs
│ ├── IForeignKeyPropertyResolver.cs
│ ├── IKeyPropertyResolver.cs
│ ├── IPropertyResolver.cs
│ ├── ISqlBuilder.cs
│ ├── ITableNameResolver.cs
│ ├── IgnoreAttribute.cs
│ ├── Insert.cs
│ ├── MultiMap.cs
│ ├── MySqlSqlBuilder.cs
│ ├── PostgresSqlBuilder.cs
│ ├── Project.cs
│ ├── Resolvers.cs
│ ├── Select.cs
│ ├── SqlExpression.cs
│ ├── SqlServerCeSqlBuilder.cs
│ ├── SqlServerSqlBuilder.cs
│ ├── SqliteSqlBuilder.cs
│ └── Update.cs
├── EmbeddedAssemblyResourceDbMetadataFactory.cs
├── FluentMap.Dommel
│ ├── FluentMapConfigurationExtensions.cs
│ ├── Mapping
│ │ ├── DommelEntityMap.cs
│ │ └── DommelPropertyMap.cs
│ └── Resolvers
│ │ ├── DommelColumnNameResolver.cs
│ │ ├── DommelKeyPropertyResolver.cs
│ │ ├── DommelPropertyResolver.cs
│ │ └── DommelTableNameResolver.cs
├── FluentMap
│ ├── Configuration
│ │ ├── FluentConventionConfiguration.cs
│ │ └── FluentMapConfiguration.cs
│ ├── Conventions
│ │ ├── Convention.cs
│ │ ├── ConventionPropertyConfiguration.cs
│ │ └── PropertyConventionConfiguration.cs
│ ├── FluentMapper.cs
│ ├── Mapping
│ │ ├── EntityMap.cs
│ │ └── PropertyMap.cs
│ ├── TypeMaps
│ │ ├── FluentConventionTypeMap.cs
│ │ ├── FluentTypeMap.cs
│ │ ├── IgnoredPropertyInfo.cs
│ │ └── MultiTypeMap.cs
│ └── Utils
│ │ ├── DictionaryExtensions.cs
│ │ └── ReflectionHelper.cs
├── IDapperContext.cs
├── IDbProvider.cs
├── Repositories
│ ├── DapperRepository.cs
│ └── IDapperRepository.cs
├── TimeSpanParseRuleAttribute.cs
├── Util
│ ├── Configuration.cs
│ ├── DBConnectionManager.cs
│ ├── DataBase.cs
│ ├── DynamicExpression.cs
│ ├── IDbConnectionManager.cs
│ ├── ObjectUtils.cs
│ └── PropertiesParser.cs
└── dbproviders.netstandard.properties
├── AA.FrameWork.Tests.Unit
├── AA.FrameWork.Tests.Unit.csproj
├── AutoMapper
│ ├── AutoMapperTest.cs
│ ├── UserVm.cs
│ └── WebMapperConfigurations.cs
├── Log4Net
│ ├── log4net.config
│ └── log4netTest.cs
├── NLog
│ ├── NLogTest.cs
│ └── nlog.config
├── RabbitMQ
│ └── ServiceBus
│ │ ├── Consumer.cs
│ │ ├── Producer.cs
│ │ └── meesageContracts
│ │ ├── OrderSubmitted.cs
│ │ └── SubmitOrder.cs
└── dapper
│ ├── AADapperContext.cs
│ ├── AADapperRepositoryMysqlTest.cs
│ ├── AADapperRepositoryTest.cs
│ ├── Advanced
│ └── DbDataSourceText.cs
│ ├── DapperContextTest.cs
│ ├── Entity
│ ├── User.cs
│ ├── UserInfo.cs
│ └── Village.cs
│ ├── EntityMap
│ ├── UserInfoMap.cs
│ ├── UserMap.cs
│ └── VillageMap.cs
│ ├── Init
│ └── DbEntityMap.cs
│ └── Repository
│ ├── IUserInfoRepository.cs
│ ├── IUserRepository.cs
│ ├── IVillageRepository.cs
│ ├── UserInfoRepository.cs
│ ├── UserRepository.cs
│ └── VillageRepository.cs
├── AA.FrameWork
├── AA.FrameWork.csproj
├── AAException.cs
├── Application
│ └── Services
│ │ └── Dto
│ │ ├── IListResult.cs
│ │ ├── IPagedResult.cs
│ │ ├── IPagedResultRequestDto.cs
│ │ ├── ListResultDto.cs
│ │ ├── PagedResultDto.cs
│ │ └── PagedResultRequestDto.cs
├── Domain
│ ├── IEntity.cs
│ ├── IPage.cs
│ ├── ISoftDelete.cs
│ ├── Page.cs
│ └── PageRequest.cs
├── Engine
│ ├── AAEngine.cs
│ ├── BaseSingleton.cs
│ ├── DependencyManagement
│ │ └── IDependencyRegistrar.cs
│ ├── EngineContext.cs
│ ├── IEngine.cs
│ ├── ITypeFinder.cs
│ ├── Singleton.cs
│ ├── SingletonDictionary.cs
│ └── SingletonList.cs
├── Extensions
│ ├── DateTimeExtension.cs
│ ├── GuidExtension.cs
│ ├── ObjectExtension.cs
│ └── StringExtensions.cs
├── Logging
│ ├── ILogger.cs
│ ├── Ilog.cs
│ └── Logger.cs
├── ObjectMapping
│ ├── IObjectMapper.cs
│ └── ObjectMapManager.cs
├── Serialize
│ └── ISerialize.cs
└── Util
│ ├── CodeUtil.cs
│ ├── ForCallContext.cs
│ └── TaskUtil.cs
├── AA.Log4Net
├── AA.Log4Net.csproj
├── Log4NetLog.cs
└── Log4NetLogger.cs
├── AA.NLog
├── AA.NLog.csproj
├── NLogLog.cs
└── NLogLogger.cs
├── AA.RabbitMQ
├── AA.RabbitMQ.csproj
├── EventMessage.cs
├── MqConfigDom.cs
├── MqConfigDomFactory.cs
├── RabbitMqClientContext.cs
├── RabbitMqClientFactory.cs
└── RabbitMqHelper.cs
├── AA.Redis
├── AA.Redis.csproj
├── Contracts
│ ├── BitfieldType.cs
│ ├── IContext.cs
│ ├── ISerializer.cs
│ ├── OverflowType.cs
│ ├── Providers
│ │ ├── ICacheProvider.cs
│ │ ├── ICacheProviderAsync.cs
│ │ └── ICollectionProvider.cs
│ ├── RedisObjects
│ │ ├── IRedisBitmap.cs
│ │ ├── IRedisDictionary.cs
│ │ ├── IRedisDictionaryAsync.cs
│ │ ├── IRedisLexicographicSet.cs
│ │ ├── IRedisList.cs
│ │ ├── IRedisListAsync.cs
│ │ ├── IRedisObject.cs
│ │ ├── IRedisSet.cs
│ │ ├── IRedisSetAsync.cs
│ │ ├── IRedisSortedSet.cs
│ │ ├── IRedisString.cs
│ │ └── IRedisStringAsync.cs
│ ├── SortedMember.cs
│ ├── TextAttribute.cs
│ └── When.cs
├── Lua
│ └── Unlock.lua
├── LuaScriptResource.cs
├── Providers
│ ├── RedisCacheProvider.cs
│ ├── RedisCollectionProvider.cs
│ ├── RedisProviderBase.cs
│ └── RedisProviderContext.cs
├── RedisContext.cs
├── RedisLock
│ ├── LockInfo.cs
│ ├── LockServerInfo.cs
│ └── RedisLock.cs
├── RedisObjects
│ ├── IRedisBitmap.cs
│ ├── RedisBaseObject.cs
│ ├── RedisBitmap.cs
│ ├── RedisDictionary.cs
│ ├── RedisLexicographicSet.cs
│ ├── RedisList.cs
│ ├── RedisSet.cs
│ ├── RedisSortedSet.cs
│ └── RedisString.cs
├── Serializers
│ └── JsonSerializer.cs
├── TaskExtensions.cs
└── Util
│ └── EmbeddedResourceLoader.cs
├── AA.ServiceBus
├── AA.ServiceBus.csproj
├── Configuration
│ └── ServiceBusConfiguration.cs
└── ServiceBusManager.cs
├── AA.sln
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/AA.AspNetCore/AA.AspNetCore.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0;netcoreapp3.1
5 | AspNetCore 常用的
6 | https://github.com/ChengLab/AAFrameWork
7 | https://github.com/ChengLab/AAFrameWork
8 | git
9 | netcore
10 | true
11 | 6.0.4
12 | 2.0.1.0
13 | 2.0.1.0
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/AA.AspNetCore/Results/Result.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | namespace AA.AspNetCore.Results
7 | {
8 |
9 | public class Result : Result
10 | {
11 | public T Data { get; set; }
12 |
13 | public static Result Response(bool isSuccess, T data, string code = "", string msg = "")
14 | {
15 | return new Result
16 | {
17 | IsSuccess = isSuccess,
18 | Message = msg,
19 | Code = code,
20 | Data = data
21 | };
22 | }
23 | }
24 | public class Result
25 | {
26 |
27 | public bool IsSuccess { get; set; }
28 | public string Message { get; set; }
29 | public string Code { get; set; }
30 | public Result() { }
31 | public Result(bool isSuccess, string code, string msg)
32 | {
33 | this.IsSuccess = isSuccess;
34 | this.Message = msg;
35 | this.Code = code;
36 | }
37 | public static Result ResponseSuccess(string msg = "", string code = "")
38 | {
39 | return new Result(true, code, msg);
40 | }
41 |
42 | public static Result ResponseError(string msg = "", string code = "")
43 | {
44 | return new Result(false, code, msg);
45 | }
46 | public static Result Response(bool isSuccess, T data, string code = "", string msg = "")
47 | {
48 | return new Result
49 | {
50 | IsSuccess = isSuccess,
51 | Message = msg,
52 | Code = code,
53 | Data = data
54 | };
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/AA.AutoMapper/AA.AutoMapper.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0;netcoreapp3.1
5 | true
6 | ChengTian
7 | AA
8 | AA
9 | AutoMapper
10 | AA;AutoMapper;
11 | https://github.com/ChengLab/AAFrameWork
12 | https://github.com/ChengLab/AAFrameWork
13 | git
14 | 3.1.0
15 | 2.0.1.0
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/AA.AutoMapper/AutoMapperConfiguration.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace AA.AutoMapper
7 | {
8 | public static class AutoMapperConfiguration
9 | {
10 | private static MapperConfiguration _mapperConfiguration;
11 | private static IMapper _mapper;
12 |
13 | public static void Init(List> configurationActions)
14 | {
15 | if (configurationActions == null)
16 | throw new ArgumentNullException("configurationActions");
17 |
18 | _mapperConfiguration = new MapperConfiguration(cfg =>
19 | {
20 | foreach (var ca in configurationActions)
21 | {
22 | ca(cfg);
23 | }
24 | });
25 | _mapper = _mapperConfiguration.CreateMapper();
26 | }
27 | public static MapperConfiguration MapperConfiguration
28 | {
29 | get { return _mapperConfiguration; }
30 | }
31 |
32 | public static IMapper Mapper => _mapper;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/AA.AutoMapper/AutoMapperObjectMapper.cs:
--------------------------------------------------------------------------------
1 | using AA.FrameWork.ObjectMapping;
2 | using AutoMapper;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 | using IObjectMapper = AA.FrameWork.ObjectMapping.IObjectMapper;
7 | namespace AA.AutoMapper
8 | {
9 | public class AutoMapperObjectMapper : IObjectMapper
10 | {
11 | private readonly IMapper _mapper;
12 |
13 | public AutoMapperObjectMapper()
14 | {
15 | _mapper = AutoMapperConfiguration.Mapper;
16 | }
17 | public TDestination Map(object source)
18 | {
19 | return _mapper.Map(source);
20 | }
21 |
22 | public TDestination Map(TSource source)
23 | {
24 | return _mapper.Map(source);
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/AA.AutoMapper/IMapperConfiguration.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace AA.AutoMapper
7 | {
8 | public interface IMapperConfiguration
9 | {
10 | Action GetConfiguration();
11 |
12 | int Order { get; }
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/AA.Dapper/AA.Dapper.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0;netcoreapp3.1
5 | LiMingCheng
6 | AA
7 | AA
8 | AA.Dapper 基于dapper+dommel 开发 , 支持工作单元、仓储模式、读写分离和原生dapper的操作
9 | https://github.com/ChengLab/AAFrameWork
10 | https://github.com/ChengLab/AAFrameWork
11 | git
12 | AA;Dapper;dommel;
13 | true
14 | 2.0.5.0
15 | 2.0.5.0
16 | 5.0.2
17 | preview
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/AA.Dapper/Advanced/Attributes/DataSourceAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace AA.Dapper.Advanced
6 | {
7 | ///
8 | /// 数据源类型 master slave
9 | ///
10 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
11 | public class DataSourceAttribute:Attribute
12 | {
13 | private string _DataSourceType;
14 | public DataSourceAttribute(string dsType)
15 | {
16 | _DataSourceType = dsType;
17 | }
18 |
19 | public string DataSourceType
20 | {
21 | get { return _DataSourceType; }
22 | set { _DataSourceType = value; }
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/AA.Dapper/Advanced/Attributes/TransactionAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace AA.Dapper.Advanced
6 | {
7 | ///
8 | /// 事务标记
9 | ///
10 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
11 | public class TransactionAttribute : Attribute
12 | {
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/AA.Dapper/Advanced/DbContextHolder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Threading;
5 | using AA.FrameWork;
6 | namespace AA.Dapper.Advanced
7 | {
8 | public static class DbContextHolder
9 | {
10 | private static AsyncLocal asyncLocal = new AsyncLocal();
11 |
12 | public static string _master = "master";
13 |
14 | public static string _slave = "slave";
15 | public static string GetDbSourceMode()
16 | {
17 | if (string.IsNullOrEmpty(asyncLocal.Value))
18 | {
19 | return _master;
20 | }
21 | return asyncLocal.Value;
22 | }
23 |
24 | public static void SetDbSourceMode(string dbType)
25 | {
26 | if (string.IsNullOrEmpty(dbType))
27 | {
28 | throw new AAException("DbContextHolder SetDbSourceMode set dbType not null");
29 | }
30 | asyncLocal.Value = dbType;
31 | }
32 |
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/AA.Dapper/Advanced/DbDataSource.cs:
--------------------------------------------------------------------------------
1 | using AA.Dapper.Util;
2 | using AA.FrameWork;
3 | using AA.FrameWork.Extensions;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Collections.Specialized;
7 | using System.Text;
8 |
9 | namespace AA.Dapper.Advanced
10 | {
11 | public class DbDataSource : IDbDatasource
12 | {
13 | public const string PropertyDataSourcePrefix = "aa.dataSource";
14 | public const string PropertyDataSourceProvider = "provider";
15 | public const string PropertyDataSourceConnectionString = "connectionString";
16 |
17 | private static readonly DbDataSource dbDataSource = new DbDataSource();
18 |
19 | private AAException initException;
20 | private PropertiesParser cfg;
21 |
22 | public static IDbDatasource Instance => dbDataSource;
23 | public void Init(NameValueCollection props)
24 | {
25 | IDbConnectionManager dbMgr = null;
26 | cfg = new PropertiesParser(props);
27 |
28 | var dsNames = cfg.GetPropertyGroups(PropertyDataSourcePrefix);
29 | foreach (string dataSourceName in dsNames)
30 | {
31 | string datasourceKey = "{0}.{1}".FormatInvariant(PropertyDataSourcePrefix, dataSourceName);
32 | NameValueCollection propertyGroup = cfg.GetPropertyGroup(datasourceKey, true);
33 | PropertiesParser pp = new PropertiesParser(propertyGroup);
34 | string dsProvider = pp.GetStringProperty(PropertyDataSourceProvider, null);
35 | string dsConnectionString = pp.GetStringProperty(PropertyDataSourceConnectionString, null);
36 |
37 | if (dsProvider == null)
38 | {
39 | initException = new AAException("Provider not specified for DataSource: {0}".FormatInvariant(dataSourceName));
40 | throw initException;
41 | }
42 | if (dsConnectionString == null)
43 | {
44 | initException = new AAException("Connection string not specified for DataSource: {0}".FormatInvariant(dataSourceName));
45 | throw initException;
46 | }
47 | try
48 | {
49 | DbProvider dbp = new DbProvider(dsProvider, dsConnectionString);
50 | dbp.Initialize();
51 |
52 | dbMgr = DBConnectionManager.Instance;
53 | dbMgr.AddConnectionProvider(dataSourceName, dbp);
54 |
55 | }
56 | catch (Exception exception)
57 | {
58 | initException = new AAException("Could not Initialize DataSource: {0}".FormatInvariant(dataSourceName), exception);
59 | throw initException;
60 | }
61 | }
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/AA.Dapper/Advanced/IDbDatasource.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Collections;
5 | using System.Collections.Specialized;
6 |
7 | namespace AA.Dapper.Advanced
8 | {
9 | public interface IDbDatasource
10 | {
11 | void Init(NameValueCollection props);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/AA.Dapper/Advanced/Interceptor/DataSourceInterceptor.cs:
--------------------------------------------------------------------------------
1 | using Castle.DynamicProxy;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace AA.Dapper.Advanced
7 | {
8 | public class DataSourceInterceptor : IInterceptor
9 | {
10 | public void Intercept(IInvocation invocation)
11 | {
12 | var customAttrs = invocation.MethodInvocationTarget.GetCustomAttributes(true);
13 | foreach (var attr in customAttrs)
14 | {
15 | var dataSource = attr as DataSourceAttribute;
16 | if (dataSource != null)
17 | {
18 | DbContextHolder.SetDbSourceMode(dataSource.DataSourceType);
19 | }
20 | }
21 | invocation.Proceed();
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/AA.Dapper/Advanced/Interceptor/TransactionInterceptor.cs:
--------------------------------------------------------------------------------
1 | using AA.FrameWork.Engine;
2 | using Castle.DynamicProxy;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace AA.Dapper.Advanced
8 | {
9 | public class TransactionInterceptor : IInterceptor
10 | {
11 | private IDapperContext dapperContext;
12 | public void Intercept(IInvocation invocation)
13 | {
14 | var customAttrs = invocation.MethodInvocationTarget.GetCustomAttributes(true);
15 | foreach (var attr in customAttrs)
16 | {
17 | var transactionAttribute = attr as TransactionAttribute;
18 | if (transactionAttribute != null)
19 | {
20 | //事务操作默认在主库上进行
21 | DbContextHolder.SetDbSourceMode("master");
22 | dapperContext = EngineContext.Current.Resolve();
23 | using (var dbtransaction = dapperContext.BeginTransaction())
24 | {
25 | try
26 | {
27 | invocation.Proceed();
28 | dbtransaction.Commit();
29 | }
30 | catch (Exception ex)
31 | {
32 | Console.Write(ex.Message);
33 | dbtransaction.Rollback();
34 | throw new Exception(ex.Message);
35 | }
36 | }
37 | }
38 | }
39 | invocation.Proceed();
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/AA.Dapper/Configuration/IMapConfiguration.cs:
--------------------------------------------------------------------------------
1 | using AA.Dapper.FluentMap.Configuration;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace AA.Dapper.Configuration
9 | {
10 | public interface IMapConfiguration
11 | {
12 | public Action GetConfiguration();
13 |
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/AA.Dapper/Configuration/MapConfiguration.cs:
--------------------------------------------------------------------------------
1 | using AA.Dapper.FluentMap;
2 | using AA.Dapper.FluentMap.Configuration;
3 | using AA.Dapper.FluentMap.Dommel;
4 | using System;
5 | using System.Collections.Generic;
6 |
7 | namespace AA.Dapper.Configuration
8 | {
9 | public static class MapConfiguration
10 | {
11 | public static void Init(List> configures)
12 | {
13 | FluentMapper.Initialize(config =>
14 | {
15 | foreach (var a in configures)
16 | {
17 | a.Invoke(config);
18 | };
19 | config.ForDommel();
20 | });
21 | }
22 | public static void Init(Action configure)
23 | {
24 | FluentMapper.Initialize(config =>
25 | {
26 | configure.Invoke(config);
27 | config.ForDommel();
28 | });
29 | }
30 |
31 | }
32 | }
--------------------------------------------------------------------------------
/AA.Dapper/ConfigurationBasedDbMetadataFactory.cs:
--------------------------------------------------------------------------------
1 |
2 | using AA.Dapper.Util;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Collections.Specialized;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 |
10 | namespace AA.Dapper
11 | {
12 | ///
13 | /// The DbMetadata factory based on application configuration
14 | ///
15 | public class ConfigurationBasedDbMetadataFactory : DbMetadataFactory
16 | {
17 | private readonly string sectionName;
18 | private readonly string providerNamePrefix;
19 |
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | /// Name of the configuration section.
24 | /// The provider name prefix.
25 | /// The providerNamePrefix cannot be null or empty.
26 | public ConfigurationBasedDbMetadataFactory(string sectionName, string providerNamePrefix)
27 | {
28 | if (string.IsNullOrEmpty(providerNamePrefix))
29 | {
30 | throw new ArgumentNullException(nameof(providerNamePrefix));
31 | }
32 |
33 | this.sectionName = sectionName;
34 | this.providerNamePrefix = providerNamePrefix;
35 | }
36 |
37 | ///
38 | /// Gets the properties parser.
39 | ///
40 | /// The properties parser
41 | protected virtual PropertiesParser GetPropertiesParser()
42 | {
43 | var settings = Util.Configuration.GetSection(sectionName) ?? new NameValueCollection();
44 | var result = new PropertiesParser(settings);
45 | return result;
46 | }
47 |
48 | ///
49 | /// Gets the supported provider names.
50 | ///
51 | /// The enumeration of the supported provider names
52 | public override IReadOnlyCollection GetProviderNames()
53 | {
54 | PropertiesParser pp = GetPropertiesParser();
55 | var result = pp.GetPropertyGroups(providerNamePrefix);
56 | return result;
57 | }
58 |
59 | ///
60 | /// Gets the database metadata associated to the specified provider name.
61 | ///
62 | /// Name of the provider.
63 | /// The metadata instance for the specified name
64 | public override DbMetadata GetDbMetadata(string providerName)
65 | {
66 | try
67 | {
68 | PropertiesParser pp = GetPropertiesParser();
69 | NameValueCollection props = pp.GetPropertyGroup(providerNamePrefix + "." + providerName, true);
70 | DbMetadata metadata = new DbMetadata();
71 |
72 | ObjectUtils.SetObjectProperties(metadata, props);
73 | metadata.Init();
74 |
75 | return metadata;
76 | }
77 | catch (Exception ex)
78 | {
79 | throw new ArgumentException("Error while reading metadata information for provider '" + providerName + "'", nameof(providerName), ex);
80 | }
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/AA.Dapper/DapperContext.cs:
--------------------------------------------------------------------------------
1 | using AA.Dapper.Advanced;
2 | using AA.Dapper.Util;
3 | using AA.FrameWork.Extensions;
4 | using AA.FrameWork.Util;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Collections.Specialized;
8 | using System.Configuration;
9 | using System.Data;
10 | using System.Data.SqlClient;
11 | namespace AA.Dapper
12 | {
13 | public class DapperContext : IDapperContext
14 | {
15 | private IDbConnection _connection = null;
16 | private IDbTransaction _dbTransaction = null;
17 |
18 | public DataBase DataBase
19 | {
20 | get
21 | {
22 | return new DataBase(this);
23 | }
24 | }
25 | ///
26 | /// Get or set the database connection manager.
27 | ///
28 | public IDbConnectionManager ConnectionManager { get; set; } = DBConnectionManager.Instance;
29 | public IDbConnection Connection
30 | {
31 | get
32 | {
33 | if (_connection == null)
34 | {
35 | var prefixDataSource = DbContextHolder.GetDbSourceMode();
36 | _connection = ConnectionManager.GetConnection(prefixDataSource);
37 | }
38 | return _connection;
39 | }
40 | }
41 |
42 | public IDbTransaction dbTransaction { get { return _dbTransaction; } }
43 | public void Dispose()
44 | {
45 | if (_connection != null && _connection.State == ConnectionState.Open)
46 | _connection.Close();
47 | }
48 |
49 |
50 | public IDbTransaction BeginTransaction(IsolationLevel isolationLevel = IsolationLevel.ReadCommitted)
51 | {
52 | if (Connection.State != ConnectionState.Open)
53 | {
54 | Connection.Open();
55 | }
56 | _dbTransaction = Connection.BeginTransaction(isolationLevel);
57 | return dbTransaction;
58 | }
59 |
60 | public void Commit()
61 | {
62 | _dbTransaction.Commit();
63 | _dbTransaction = null;
64 | }
65 |
66 | public void RollBack()
67 | {
68 | _dbTransaction.Rollback();
69 | }
70 |
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/AA.Dapper/DbMetadataFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace AA.Dapper
8 | {
9 | ///
10 | /// Base class for the DbMetadata Factory implementations
11 | ///
12 | public abstract class DbMetadataFactory
13 | {
14 | ///
15 | /// Gets the supported provider names.
16 | ///
17 | /// The enumeration of the supported provider names
18 | public abstract IReadOnlyCollection GetProviderNames();
19 |
20 | ///
21 | /// Gets the database metadata associated to the specified provider name.
22 | ///
23 | /// Name of the provider.
24 | /// The metadata instance for the requested provider
25 | public abstract DbMetadata GetDbMetadata(string providerName);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/Cache.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 |
4 | namespace AA.Dapper.Dommel
5 | {
6 | internal enum QueryCacheType
7 | {
8 | Get,
9 | GetByMultipleIds,
10 | GetAll,
11 | Project,
12 | ProjectAll,
13 | Count,
14 | Insert,
15 | Update,
16 | Delete,
17 | DeleteAll,
18 | Any,
19 | }
20 |
21 | internal struct QueryCacheKey : IEquatable
22 | {
23 | public QueryCacheKey(QueryCacheType cacheType, ISqlBuilder sqlBuilder, MemberInfo memberInfo)
24 | {
25 | SqlBuilderType = sqlBuilder.GetType();
26 | CacheType = cacheType;
27 | MemberInfo = memberInfo;
28 | }
29 |
30 | public QueryCacheType CacheType { get; }
31 |
32 | public Type SqlBuilderType { get; }
33 |
34 | public MemberInfo MemberInfo { get; }
35 |
36 | public bool Equals(QueryCacheKey other) => CacheType == other.CacheType && SqlBuilderType == other.SqlBuilderType && MemberInfo == other.MemberInfo;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/ColumnPropertyInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel.DataAnnotations.Schema;
3 | using System.Reflection;
4 |
5 | namespace AA.Dapper.Dommel
6 | {
7 | ///
8 | /// Represents the column of an entity.
9 | ///
10 | public class ColumnPropertyInfo
11 | {
12 | ///
13 | /// Initializes a new instance from the
14 | /// specified instance.
15 | ///
16 | ///
17 | /// The property which represents the database column. The is
18 | /// determined from the option specified on
19 | /// the property. Defaults to when
20 | /// is true; otherwise, .
21 | ///
22 | /// Indicates whether a property is a key column.
23 | public ColumnPropertyInfo(PropertyInfo property, bool isKey = false)
24 | {
25 | Property = property ?? throw new ArgumentNullException(nameof(property));
26 | GeneratedOption = property.GetCustomAttribute()?.DatabaseGeneratedOption
27 | ?? (isKey ? DatabaseGeneratedOption.Identity : DatabaseGeneratedOption.None);
28 | }
29 |
30 | ///
31 | /// Initializes a new instance from the
32 | /// specified instance using the specified
33 | /// .
34 | ///
35 | /// The property which represents the database column.
36 | ///
37 | /// The which specifies whether the value of
38 | /// the column this property represents is generated by the database.
39 | ///
40 | public ColumnPropertyInfo(PropertyInfo property, DatabaseGeneratedOption generatedOption)
41 | {
42 | Property = property ?? throw new ArgumentNullException(nameof(property));
43 | GeneratedOption = generatedOption;
44 | }
45 |
46 | ///
47 | /// Gets a reference to the instance.
48 | ///
49 | public PropertyInfo Property { get; }
50 |
51 | ///
52 | /// Gets the which specifies whether the value of
53 | /// the column this property represents is generated by the database.
54 | ///
55 | public DatabaseGeneratedOption GeneratedOption { get; }
56 |
57 | ///
58 | /// Gets a value indicating whether this key property's value is generated by the database.
59 | ///
60 | public bool IsGenerated => GeneratedOption != DatabaseGeneratedOption.None;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/DefaultColumnNameResolver.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations.Schema;
2 | using System.Reflection;
3 |
4 | namespace AA.Dapper.Dommel
5 | {
6 | ///
7 | /// Implements the .
8 | ///
9 | public class DefaultColumnNameResolver : IColumnNameResolver
10 | {
11 | ///
12 | /// Resolves the column name for the property.
13 | /// Looks for the [Column] attribute. Otherwise it's just the name of the property.
14 | ///
15 | public virtual string ResolveColumnName(PropertyInfo propertyInfo)
16 | {
17 | var columnAttr = propertyInfo.GetCustomAttribute();
18 | if (columnAttr != null)
19 | {
20 | return columnAttr.Name;
21 | }
22 |
23 | return propertyInfo.Name;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/DefaultKeyPropertyResolver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel.DataAnnotations;
3 | using System.Linq;
4 | using System.Reflection;
5 |
6 | namespace AA.Dapper.Dommel
7 | {
8 | ///
9 | /// Implements the interface by resolving key properties
10 | /// with the [] or with the name 'Id'.
11 | ///
12 | public class DefaultKeyPropertyResolver : IKeyPropertyResolver
13 | {
14 | ///
15 | /// Finds the key properties by looking for properties with the
16 | /// [] attribute or with the name 'Id'.
17 | ///
18 | public ColumnPropertyInfo[] ResolveKeyProperties(Type type)
19 | {
20 | var keyProps = Resolvers
21 | .Properties(type)
22 | .Select(x => x.Property)
23 | .Where(p => string.Equals(p.Name, "Id", StringComparison.OrdinalIgnoreCase) || p.GetCustomAttribute() != null)
24 | .ToArray();
25 |
26 | if (keyProps.Length == 0)
27 | {
28 | throw new InvalidOperationException($"Could not find the key properties for type '{type.FullName}'.");
29 | }
30 |
31 | return keyProps.Select(p => new ColumnPropertyInfo(p, isKey: true)).ToArray();
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/DefaultPropertyResolver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.DataAnnotations.Schema;
4 | using System.Reflection;
5 |
6 | namespace AA.Dapper.Dommel
7 | {
8 | ///
9 | /// Default implemenation of the interface.
10 | ///
11 | public class DefaultPropertyResolver : IPropertyResolver
12 | {
13 | private static readonly HashSet PrimitiveTypesSet = new HashSet
14 | {
15 | typeof(object),
16 | typeof(string),
17 | typeof(Guid),
18 | typeof(decimal),
19 | typeof(double),
20 | typeof(float),
21 | typeof(DateTime),
22 | typeof(DateTimeOffset),
23 | typeof(TimeSpan),
24 | typeof(byte[]),
25 | };
26 |
27 | ///
28 | /// Resolves the properties to be mapped for the specified type.
29 | ///
30 | /// The type to resolve the properties to be mapped for.
31 | /// A collection of 's of the .
32 | public virtual IEnumerable ResolveProperties(Type type)
33 | {
34 | foreach (var property in FilterComplexTypes(type.GetRuntimeProperties()))
35 | {
36 | if (!property.IsDefined(typeof(IgnoreAttribute)) && !property.IsDefined(typeof(NotMappedAttribute)))
37 | {
38 | yield return new ColumnPropertyInfo(property);
39 | }
40 | }
41 | }
42 |
43 | ///
44 | /// Gets a collection of types that are considered 'primitive' for Dommel but are not for the CLR.
45 | /// Override this to specify your own set of types.
46 | ///
47 | protected virtual HashSet PrimitiveTypes => PrimitiveTypesSet;
48 |
49 | ///
50 | /// Filters the complex types from the specified collection of properties.
51 | ///
52 | /// A collection of properties.
53 | /// The properties that are considered 'primitive' of .
54 | protected virtual IEnumerable FilterComplexTypes(IEnumerable properties)
55 | {
56 | foreach (var property in properties)
57 | {
58 | var type = property.PropertyType;
59 | type = Nullable.GetUnderlyingType(type) ?? type;
60 | if (type.GetTypeInfo().IsPrimitive || type.GetTypeInfo().IsEnum || PrimitiveTypes.Contains(type))
61 | {
62 | yield return property;
63 | }
64 | }
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/DefaultTableNameResolver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel.DataAnnotations.Schema;
3 | using System.Reflection;
4 |
5 | namespace AA.Dapper.Dommel
6 | {
7 | ///
8 | /// Default implementation of the interface.
9 | ///
10 | public class DefaultTableNameResolver : ITableNameResolver
11 | {
12 | ///
13 | /// Resolves the table name.
14 | /// Looks for the [Table] attribute. Otherwise by making the type
15 | /// plural (eg. Product -> Products) and removing the 'I' prefix for interfaces.
16 | ///
17 | public virtual string ResolveTableName(Type type)
18 | {
19 | var typeInfo = type.GetTypeInfo();
20 | var tableAttr = typeInfo.GetCustomAttribute();
21 | if (tableAttr != null)
22 | {
23 | if (!string.IsNullOrEmpty(tableAttr.Schema))
24 | {
25 | return $"{tableAttr.Schema}.{tableAttr.Name}";
26 | }
27 |
28 | return tableAttr.Name;
29 | }
30 |
31 | // Fall back to plural of table name
32 | var name = type.Name;
33 | if (name.EndsWith("y", StringComparison.OrdinalIgnoreCase))
34 | {
35 | // Category -> Categories
36 | name = name.Remove(name.Length - 1) + "ies";
37 | }
38 | else if (!name.EndsWith("s", StringComparison.OrdinalIgnoreCase))
39 | {
40 | // Product -> Products
41 | name += "s";
42 | }
43 |
44 | return name;
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/ForeignKeyRelation.cs:
--------------------------------------------------------------------------------
1 | namespace AA.Dapper.Dommel
2 | {
3 | ///
4 | /// Describes a foreign key relationship.
5 | ///
6 | public enum ForeignKeyRelation
7 | {
8 | ///
9 | /// Specifies a one-to-one relationship.
10 | ///
11 | OneToOne,
12 |
13 | ///
14 | /// Specifies a one-to-many relationship.
15 | ///
16 | OneToMany
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/From.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Data;
4 | using System.Threading.Tasks;
5 | using Dapper;
6 |
7 | namespace AA.Dapper.Dommel
8 | {
9 | public static partial class DommelMapper
10 | {
11 | ///
12 | /// Executes an expression to query data from .
13 | ///
14 | /// The entity to query data from.
15 | /// The connection to query data from.
16 | /// A callback to build a .
17 | /// Optional transaction for the command.
18 | ///
19 | /// A value indicating whether the result of the query should be executed directly,
20 | /// or when the query is materialized (using ToList() for example).
21 | ///
22 | /// The collection of entities returned from the query.
23 | public static IEnumerable From(this IDbConnection con, Action> sqlBuilder, IDbTransaction? transaction = null, bool buffered = true)
24 | {
25 | var sqlExpression = CreateSqlExpression(GetSqlBuilder(con));
26 | sqlBuilder(sqlExpression);
27 | var sql = sqlExpression.ToSql(out var parameters);
28 | return con.Query(sql.Replace("True","1=1"), parameters, transaction, buffered);
29 | }
30 |
31 | ///
32 | /// Executes an expression to query data from .
33 | ///
34 | /// The entity to query data from.
35 | /// The connection to query data from.
36 | /// A callback to build a .
37 | /// Optional transaction for the command.
38 | /// The collection of entities returned from the query.
39 | public static async Task> FromAsync(this IDbConnection con, Action> sqlBuilder, IDbTransaction? transaction = null)
40 | {
41 | var sqlExpression = CreateSqlExpression(GetSqlBuilder(con));
42 | sqlBuilder(sqlExpression);
43 | var sql = sqlExpression.ToSql(out var parameters);
44 | return await con.QueryAsync(sql.Replace("True", "1=1"), parameters, transaction);
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/IColumnNameResolver.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 |
3 | namespace AA.Dapper.Dommel
4 | {
5 | ///
6 | /// Defines methods for resolving column names for entities.
7 | /// Custom implementations can be registered with .
8 | ///
9 | public interface IColumnNameResolver
10 | {
11 | ///
12 | /// Resolves the column name for the specified property.
13 | ///
14 | /// The property of the entity.
15 | /// The column name for the property.
16 | string ResolveColumnName(PropertyInfo propertyInfo);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/IForeignKeyPropertyResolver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 |
4 | namespace AA.Dapper.Dommel
5 | {
6 | ///
7 | /// Defines methods for resolving foreign key properties.
8 | /// Custom implementations can be registered with .
9 | ///
10 | public interface IForeignKeyPropertyResolver
11 | {
12 | ///
13 | /// Resolves the foreign key property for the specified source type and including type.
14 | ///
15 | /// The source type which should contain the foreign key property.
16 | /// The type of the foreign key relation.
17 | /// The foreign key relationship type.
18 | /// The foreign key property for and .
19 | PropertyInfo ResolveForeignKeyProperty(Type sourceType, Type includingType, out ForeignKeyRelation foreignKeyRelation);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/IKeyPropertyResolver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 |
4 | namespace AA.Dapper.Dommel
5 | {
6 | ///
7 | /// Defines methods for resolving the key property of entities.
8 | /// Custom implementations can be registered with .
9 | ///
10 | public interface IKeyPropertyResolver
11 | {
12 | ///
13 | /// Resolves the key properties for the specified type.
14 | ///
15 | /// The type to resolve the key properties for.
16 | /// A collection of instances of the key properties of .
17 | ColumnPropertyInfo[] ResolveKeyProperties(Type type);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/IPropertyResolver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Reflection;
4 |
5 | namespace AA.Dapper.Dommel
6 | {
7 | ///
8 | /// Defines methods for resolving the properties of entities.
9 | /// Custom implementations can be registered with .
10 | ///
11 | public interface IPropertyResolver
12 | {
13 | ///
14 | /// Resolves the properties to be mapped for the specified type.
15 | ///
16 | /// The type to resolve the properties to be mapped for.
17 | /// A collection of 's of the .
18 | IEnumerable ResolveProperties(Type type);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/ISqlBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace AA.Dapper.Dommel
4 | {
5 | ///
6 | /// Defines methods for building specialized SQL queries.
7 | ///
8 | public interface ISqlBuilder
9 | {
10 | ///
11 | /// Adds a prefix to the specified parameter.
12 | ///
13 | /// The name of the parameter to prefix.
14 | string PrefixParameter(string paramName);
15 |
16 | ///
17 | /// Builds an insert query using the specified table name, column names and parameter names.
18 | /// A query to fetch the new ID will be included as well.
19 | ///
20 | /// The type of the entity to generate the insert query for.
21 | /// The name of the table to query.
22 | /// The names of the columns in the table.
23 | /// The names of the parameters in the database command.
24 | /// An insert query including a query to fetch the new ID.
25 | string BuildInsert(Type type, string tableName, string[] columnNames, string[] paramNames);
26 |
27 | ///
28 | /// Builds the paging part to be appended to an existing select query.
29 | ///
30 | /// The order by part of the query.
31 | /// The number of the page to fetch, starting at 1.
32 | /// The page size.
33 | /// The paging part of a query.
34 | string BuildPaging(string? orderBy, int pageNumber, int pageSize);
35 |
36 | ///
37 | /// Adds quotes around (or at the start) of an identifier such as a table or column name.
38 | ///
39 | /// The identifier add quotes around. E.g. a table or column name.
40 | /// The quoted .
41 | string QuoteIdentifier(string identifier);
42 |
43 | ///
44 | /// Adds a limit clause to query.
45 | ///
46 | /// The count of limit clause.
47 | /// A limit clause of the specified count.
48 | string LimitClause(int count);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/ITableNameResolver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace AA.Dapper.Dommel
4 | {
5 | ///
6 | /// Defines methods for resolving table names of entities.
7 | /// Custom implementations can be registered with .
8 | ///
9 | public interface ITableNameResolver
10 | {
11 | ///
12 | /// Resolves the table name for the specified type.
13 | ///
14 | /// The type to resolve the table name for.
15 | /// A string containing the resolved table name for for .
16 | string ResolveTableName(Type type);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/IgnoreAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace AA.Dapper.Dommel
4 | {
5 | ///
6 | /// Specifies that a property should be ignored.
7 | ///
8 | [AttributeUsage(AttributeTargets.Property)]
9 | public class IgnoreAttribute : Attribute
10 | {
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/MySqlSqlBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace AA.Dapper.Dommel
4 | {
5 | ///
6 | /// implementation for MySQL.
7 | ///
8 | public class MySqlSqlBuilder : ISqlBuilder
9 | {
10 | ///
11 | public virtual string BuildInsert(Type type, string tableName, string[] columnNames, string[] paramNames) =>
12 | $"insert into {tableName} ({string.Join(", ", columnNames)}) values ({string.Join(", ", paramNames)}); select LAST_INSERT_ID() id";
13 |
14 | ///
15 | public virtual string BuildPaging(string? orderBy, int pageNumber, int pageSize)
16 | {
17 | var start = pageNumber >= 1 ? (pageNumber - 1) * pageSize : 0;
18 | return $" {orderBy} limit {start}, {pageSize}";
19 | }
20 |
21 | ///
22 | public string PrefixParameter(string paramName) => $"@{paramName}";
23 |
24 | ///
25 | public string QuoteIdentifier(string identifier) => $"`{identifier}`";
26 |
27 | ///
28 | public string LimitClause(int count) => $"limit {count}";
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/PostgresSqlBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace AA.Dapper.Dommel
5 | {
6 | ///
7 | /// implementation for Postgres.
8 | ///
9 | public class PostgresSqlBuilder : ISqlBuilder
10 | {
11 | ///
12 | public virtual string BuildInsert(Type type, string tableName, string[] columnNames, string[] paramNames)
13 | {
14 | if (type == null)
15 | {
16 | throw new ArgumentNullException(nameof(type));
17 | }
18 |
19 | var sql = $"insert into {tableName} ({string.Join(", ", columnNames)}) values ({string.Join(", ", paramNames)}) ";
20 |
21 | var keyColumns = Resolvers.KeyProperties(type).Where(p => p.IsGenerated).Select(p => Resolvers.Column(p.Property, this));
22 | if (keyColumns.Any())
23 | {
24 | sql += $"returning ({string.Join(", ", keyColumns)})";
25 | }
26 |
27 | return sql;
28 | }
29 |
30 | ///
31 | public virtual string BuildPaging(string? orderBy, int pageNumber, int pageSize)
32 | {
33 | var start = pageNumber >= 1 ? (pageNumber - 1) * pageSize : 0;
34 | return $" {orderBy} offset {start} limit {pageSize}";
35 | }
36 |
37 | ///
38 | public string PrefixParameter(string paramName) => $"@{paramName}";
39 |
40 | ///
41 | public string QuoteIdentifier(string identifier) => $"\"{identifier}\"";
42 |
43 | ///
44 | public string LimitClause(int count) => $"limit {count}";
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/SqlServerCeSqlBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace AA.Dapper.Dommel
4 | {
5 | ///
6 | /// implementation for SQL Server Compact Edition.
7 | ///
8 | public class SqlServerCeSqlBuilder : ISqlBuilder
9 | {
10 | ///
11 | public virtual string BuildInsert(Type type, string tableName, string[] columnNames, string[] paramNames) =>
12 | $"insert into {tableName} ({string.Join(", ", columnNames)}) values ({string.Join(", ", paramNames)}); select @@IDENTITY";
13 |
14 | ///
15 | public virtual string BuildPaging(string? orderBy, int pageNumber, int pageSize)
16 | {
17 | var start = pageNumber >= 1 ? (pageNumber - 1) * pageSize : 0;
18 | return $" {orderBy} offset {start} rows fetch next {pageSize} rows only";
19 | }
20 |
21 | ///
22 | public string PrefixParameter(string paramName) => $"@{paramName}";
23 |
24 | ///
25 | public string QuoteIdentifier(string identifier) => $"[{identifier}]";
26 |
27 | ///
28 | public string LimitClause(int count) => $"order by 1 offset 0 rows fetch next {count} rows only";
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/SqlServerSqlBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace AA.Dapper.Dommel
4 | {
5 | ///
6 | /// implementation for SQL Server.
7 | ///
8 | public class SqlServerSqlBuilder : ISqlBuilder
9 | {
10 | ///
11 | public virtual string BuildInsert(Type type, string tableName, string[] columnNames, string[] paramNames) =>
12 | $"set nocount on insert into {tableName} ({string.Join(", ", columnNames)}) values ({string.Join(", ", paramNames)}); select scope_identity()";
13 |
14 | ///
15 | public virtual string BuildPaging(string? orderBy, int pageNumber, int pageSize)
16 | {
17 | var start = pageNumber >= 1 ? (pageNumber - 1) * pageSize : 0;
18 | return $" {orderBy} offset {start} rows fetch next {pageSize} rows only";
19 | }
20 |
21 | ///
22 | public string PrefixParameter(string paramName) => $"@{paramName}";
23 |
24 | ///
25 | public string QuoteIdentifier(string identifier) => $"[{identifier}]";
26 |
27 | ///
28 | public string LimitClause(int count) => $"order by 1 offset 0 rows fetch next {count} rows only";
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/SqliteSqlBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace AA.Dapper.Dommel
4 | {
5 | ///
6 | /// implementation for SQLite.
7 | ///
8 | public class SqliteSqlBuilder : ISqlBuilder
9 | {
10 | ///
11 | public virtual string BuildInsert(Type type, string tableName, string[] columnNames, string[] paramNames) =>
12 | $"insert into {tableName} ({string.Join(", ", columnNames)}) values ({string.Join(", ", paramNames)}); select last_insert_rowid() id";
13 |
14 | ///
15 | public virtual string BuildPaging(string? orderBy, int pageNumber, int pageSize)
16 | {
17 | var start = pageNumber >= 1 ? (pageNumber - 1) * pageSize : 0;
18 | return $" {orderBy} LIMIT {start}, {pageSize}";
19 | }
20 |
21 | ///
22 | public string PrefixParameter(string paramName) => $"@{paramName}";
23 |
24 | ///
25 | public string QuoteIdentifier(string identifier) => identifier;
26 |
27 | ///
28 | public string LimitClause(int count) => $"limit {count}";
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/AA.Dapper/Dommel/Update.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Data;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Dapper;
6 |
7 | namespace AA.Dapper.Dommel
8 | {
9 | public static partial class DommelMapper
10 | {
11 | ///
12 | /// Updates the values of the specified entity in the database.
13 | /// The return value indicates whether the operation succeeded.
14 | ///
15 | /// The type of the entity.
16 | /// The connection to the database. This can either be open or closed.
17 | /// The entity in the database.
18 | /// Optional transaction for the command.
19 | /// A value indicating whether the update operation succeeded.
20 | public static bool Update(this IDbConnection connection, TEntity entity, IDbTransaction? transaction = null)
21 | {
22 | var sql = BuildUpdateQuery(GetSqlBuilder(connection), typeof(TEntity));
23 | LogQuery(sql);
24 | return connection.Execute(sql, entity, transaction) > 0;
25 | }
26 |
27 | ///
28 | /// Updates the values of the specified entity in the database.
29 | /// The return value indicates whether the operation succeeded.
30 | ///
31 | /// The type of the entity.
32 | /// The connection to the database. This can either be open or closed.
33 | /// The entity in the database.
34 | /// Optional transaction for the command.
35 | /// A value indicating whether the update operation succeeded.
36 | public static async Task UpdateAsync(this IDbConnection connection, TEntity entity, IDbTransaction? transaction = null)
37 | {
38 | var sql = BuildUpdateQuery(GetSqlBuilder(connection), typeof(TEntity));
39 | LogQuery(sql);
40 | return await connection.ExecuteAsync(sql, entity, transaction) > 0;
41 | }
42 |
43 | internal static string BuildUpdateQuery(ISqlBuilder sqlBuilder, Type type)
44 | {
45 | var cacheKey = new QueryCacheKey(QueryCacheType.Update, sqlBuilder, type);
46 | if (!QueryCache.TryGetValue(cacheKey, out var sql))
47 | {
48 | var tableName = Resolvers.Table(type, sqlBuilder);
49 |
50 | // Use all non-key and non-generated properties for updates
51 | var keyProperties = Resolvers.KeyProperties(type);
52 | var typeProperties = Resolvers.Properties(type)
53 | .Where(x => !x.IsGenerated)
54 | .Select(x => x.Property)
55 | .Except(keyProperties.Where(p => p.IsGenerated).Select(p => p.Property));
56 |
57 | var columnNames = typeProperties.Select(p => $"{Resolvers.Column(p, sqlBuilder)} = {sqlBuilder.PrefixParameter(p.Name)}").ToArray();
58 | var whereClauses = keyProperties.Select(p => $"{Resolvers.Column(p.Property, sqlBuilder)} = {sqlBuilder.PrefixParameter(p.Property.Name)}");
59 | sql = $"update {tableName} set {string.Join(", ", columnNames)} where {string.Join(" and ", whereClauses)}";
60 | if (sql.IndexOf("(True") != -1)
61 | {
62 | sql = sql.Replace("(True", "(1=1");
63 | }
64 | QueryCache.TryAdd(cacheKey, sql);
65 | }
66 |
67 | return sql;
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/AA.Dapper/EmbeddedAssemblyResourceDbMetadataFactory.cs:
--------------------------------------------------------------------------------
1 |
2 | using AA.Dapper.Util;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Collections.Specialized;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 |
10 | namespace AA.Dapper
11 | {
12 |
13 | public class EmbeddedAssemblyResourceDbMetadataFactory : DbMetadataFactory
14 | {
15 | private readonly string resourceName;
16 | private readonly string propertyGroupName;
17 |
18 | ///
19 | /// Initializes a new instance of the class.
20 | ///
21 | /// Name of the resource.
22 | /// Name of the property group (The prefix of the provider name).
23 | public EmbeddedAssemblyResourceDbMetadataFactory(string resourceName, string propertyGroupName)
24 | {
25 | this.resourceName = resourceName;
26 | this.propertyGroupName = propertyGroupName;
27 | }
28 |
29 | ///
30 | /// Gets the supported provider names.(获取支持的数据库)
31 | ///
32 | /// The enumeration of the supported provider names
33 | public override IReadOnlyCollection GetProviderNames()
34 | {
35 | PropertiesParser pp = PropertiesParser.ReadFromEmbeddedAssemblyResource(resourceName);
36 | var result = pp.GetPropertyGroups(propertyGroupName);
37 | return result;
38 | }
39 |
40 | ///
41 | /// Gets the database metadata associated to the specified provider name.
42 | ///
43 | /// Name of the provider.
44 | /// The metadata instance for the specified name
45 | public override DbMetadata GetDbMetadata(string providerName)
46 | {
47 | List deprecatedProviders = new List
48 | {
49 | "Npgsql-10",
50 | "SqlServer-11"
51 | };
52 |
53 | if (deprecatedProviders.Contains(providerName))
54 | {
55 | throw new Exception(providerName + " provider is no longer supported.");
56 | }
57 |
58 | try
59 | {
60 | PropertiesParser pp = PropertiesParser.ReadFromEmbeddedAssemblyResource(resourceName);
61 | NameValueCollection props = pp.GetPropertyGroup(propertyGroupName + "." + providerName, true);
62 | DbMetadata metadata = new DbMetadata();
63 |
64 | ObjectUtils.SetObjectProperties(metadata, props);
65 | metadata.Init();
66 |
67 | return metadata;
68 | }
69 | catch (Exception ex)
70 | {
71 | throw new ArgumentException("Error while reading metadata information for provider '" + providerName + "'", nameof(providerName), ex);
72 | }
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/AA.Dapper/FluentMap.Dommel/FluentMapConfigurationExtensions.cs:
--------------------------------------------------------------------------------
1 | using AA.Dapper.FluentMap.Configuration;
2 | using AA.Dapper.FluentMap.Dommel.Resolvers;
3 | using AA.Dapper.Dommel;
4 |
5 | namespace AA.Dapper.FluentMap.Dommel
6 | {
7 | ///
8 | /// Defines methods for configured Dapper.FluentMap.Dommel.
9 | ///
10 | public static class FluentMapConfigurationExtensions
11 | {
12 | ///
13 | /// Configures the specified configuration for Dapper.FluentMap.Dommel.
14 | ///
15 | /// The Dapper.FluentMap configuration.
16 | /// The Dapper.FluentMap configuration.
17 | public static FluentMapConfiguration ForDommel(this FluentMapConfiguration config)
18 | {
19 | DommelMapper.SetColumnNameResolver(new DommelColumnNameResolver());
20 | DommelMapper.SetKeyPropertyResolver(new DommelKeyPropertyResolver());
21 | DommelMapper.SetTableNameResolver(new DommelTableNameResolver());
22 | DommelMapper.SetPropertyResolver(new DommelPropertyResolver());
23 | return config;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/AA.Dapper/FluentMap.Dommel/Mapping/DommelEntityMap.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using AA.Dapper.FluentMap.Mapping;
3 |
4 | namespace AA.Dapper.FluentMap.Dommel.Mapping
5 | {
6 | ///
7 | /// Represents a non-typed mapping of an entity for Dommel.
8 | ///
9 | public interface IDommelEntityMap : IEntityMap
10 | {
11 | ///
12 | /// Gets the table name for the current entity.
13 | ///
14 | string TableName { get; }
15 | }
16 |
17 | ///
18 | /// Represents the typed mapping of an entity for Dommel.
19 | ///
20 | /// The type of an entity.
21 | public abstract class DommelEntityMap : EntityMapBase, IDommelEntityMap
22 | where TEntity : class
23 | {
24 | ///
25 | /// Gets the implementation for the current entity map.
26 | ///
27 | /// The information about the property.
28 | /// An implementation of .
29 | protected override DommelPropertyMap GetPropertyMap(PropertyInfo info)
30 | {
31 | return new DommelPropertyMap(info);
32 | }
33 |
34 | ///
35 | /// Gets the table name for this entity map.
36 | ///
37 | public string TableName { get; private set; }
38 |
39 | ///
40 | /// Sets the table name for the current entity.
41 | ///
42 | /// The name of the table in the database.
43 | protected void ToTable(string tableName)
44 | {
45 | TableName = tableName;
46 | }
47 |
48 | ///
49 | /// Sets the table name for the current entity.
50 | ///
51 | /// The name of the table in the database.
52 | /// The name of the table schema in the database.
53 | protected void ToTable(string tableName, string schemaName)
54 | {
55 | TableName = $"{schemaName}.{tableName}";
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/AA.Dapper/FluentMap.Dommel/Mapping/DommelPropertyMap.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations.Schema;
2 | using System.Reflection;
3 | using AA.Dapper.FluentMap.Mapping;
4 |
5 | namespace AA.Dapper.FluentMap.Dommel.Mapping
6 | {
7 | ///
8 | /// Represents mapping of a property for Dommel.
9 | ///
10 | public class DommelPropertyMap : PropertyMapBase, IPropertyMap
11 | {
12 | ///
13 | /// Initializes a new instance of the class
14 | /// with the specified object.
15 | ///
16 | /// The information about the property.
17 | public DommelPropertyMap(PropertyInfo info) : base(info)
18 | {
19 | }
20 |
21 | ///
22 | /// Gets a value indicating whether this property is a primary key.
23 | ///
24 | public bool Key { get; private set; }
25 |
26 | ///
27 | /// Gets a value indicating whether this primary key is an identity.
28 | ///
29 | public bool Identity { get; set; }
30 |
31 | ///
32 | /// Gets a value indicating how the column is generated.
33 | ///
34 | public DatabaseGeneratedOption GeneratedOption { get; set; } = DatabaseGeneratedOption.None;
35 |
36 | ///
37 | /// Specifies the current property as key for the entity.
38 | ///
39 | /// The current instance of .
40 | public DommelPropertyMap IsKey()
41 | {
42 | Key = true;
43 | return this;
44 | }
45 |
46 | ///
47 | /// Specifies the current property as an identity.
48 | ///
49 | /// The current instance of .
50 | public DommelPropertyMap IsIdentity()
51 | {
52 | Identity = true;
53 | return this;
54 | }
55 |
56 | ///
57 | /// Specifies how the property is generated.
58 | ///
59 | public DommelPropertyMap SetGeneratedOption(DatabaseGeneratedOption option)
60 | {
61 | GeneratedOption = option;
62 | return this;
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/AA.Dapper/FluentMap.Dommel/Resolvers/DommelColumnNameResolver.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Reflection;
3 | using AA.Dapper.FluentMap.Dommel.Mapping;
4 | using AA.Dapper.FluentMap.Mapping;
5 | using AA.Dapper.Dommel;
6 |
7 | namespace AA.Dapper.FluentMap.Dommel.Resolvers
8 | {
9 | ///
10 | /// Implements the interface by using the configured mapping.
11 | ///
12 | public class DommelColumnNameResolver : IColumnNameResolver
13 | {
14 | private static readonly IColumnNameResolver DefaultResolver = new DefaultColumnNameResolver();
15 |
16 | ///
17 | public string ResolveColumnName(PropertyInfo propertyInfo)
18 | {
19 | if (propertyInfo.DeclaringType != null)
20 | {
21 | #if NETSTANDARD1_3
22 | if (FluentMapper.EntityMaps.TryGetValue(propertyInfo.DeclaringType, out var entityMap))
23 |
24 | #else
25 | if (FluentMapper.EntityMaps.TryGetValue(propertyInfo.ReflectedType, out var entityMap))
26 | #endif
27 | {
28 | var mapping = entityMap as IDommelEntityMap;
29 | if (mapping != null)
30 | {
31 | var propertyMaps = entityMap.PropertyMaps.Where(m => m.PropertyInfo.Name == propertyInfo.Name).ToList();
32 | if (propertyMaps.Count == 1)
33 | {
34 | return propertyMaps[0].ColumnName;
35 | }
36 | }
37 | }
38 | #if NETSTANDARD1_3
39 | else if (FluentMapper.TypeConventions.TryGetValue(propertyInfo.DeclaringType, out var conventions))
40 |
41 | #else
42 | else if (FluentMapper.TypeConventions.TryGetValue(propertyInfo.ReflectedType, out var conventions))
43 | #endif
44 | {
45 | foreach (var convention in conventions)
46 | {
47 | var propertyMaps = convention.PropertyMaps.Where(m => m.PropertyInfo.Name == propertyInfo.Name).ToList();
48 | if (propertyMaps.Count == 1)
49 | {
50 | return propertyMaps[0].ColumnName;
51 | }
52 | }
53 | }
54 | }
55 |
56 | return DefaultResolver.ResolveColumnName(propertyInfo);
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/AA.Dapper/FluentMap.Dommel/Resolvers/DommelKeyPropertyResolver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Reflection;
4 | using AA.Dapper.FluentMap.Dommel.Mapping;
5 | using AA.Dapper.FluentMap.Mapping;
6 | using AA.Dapper.Dommel;
7 |
8 | namespace AA.Dapper.FluentMap.Dommel.Resolvers
9 | {
10 | ///
11 | /// Implements the interface by using the configured mapping.
12 | ///
13 | public class DommelKeyPropertyResolver : IKeyPropertyResolver
14 | {
15 | private static readonly IKeyPropertyResolver DefaultResolver = new DefaultKeyPropertyResolver();
16 |
17 | ///
18 | public ColumnPropertyInfo[] ResolveKeyProperties(Type type)
19 | {
20 | IEntityMap entityMap;
21 | if (!FluentMapper.EntityMaps.TryGetValue(type, out entityMap))
22 | {
23 | return DefaultResolver.ResolveKeyProperties(type);
24 | }
25 |
26 | var mapping = entityMap as IDommelEntityMap;
27 | if (mapping != null)
28 | {
29 | var allPropertyMaps = entityMap.PropertyMaps.OfType();
30 | var keyPropertyInfos = allPropertyMaps
31 | .Where(e => e.Key)
32 | .Select(x => new ColumnPropertyInfo(x.PropertyInfo, isKey: true))
33 | .ToArray();
34 |
35 | // Now make sure there aren't any missing key properties that weren't explicitly defined in the mapping.
36 | try
37 | {
38 | // Make sure to exclude any keys that were defined in the dommel entity map and not marked as keys.
39 | var defaultKeyPropertyInfos = DefaultResolver.ResolveKeyProperties(type).Where(x => allPropertyMaps.Count(y => y.PropertyInfo.Equals(x.Property)) == 0);
40 | keyPropertyInfos = keyPropertyInfos.Union(defaultKeyPropertyInfos).ToArray();
41 | }
42 | catch
43 | {
44 | // There could be no default Ids found. This is okay as long as we found a custom one.
45 | if (keyPropertyInfos.Length == 0)
46 | {
47 | throw new InvalidOperationException($"Could not find the key properties for type '{type.FullName}'.");
48 | }
49 | }
50 |
51 | return keyPropertyInfos;
52 | }
53 |
54 | // Fall back to the default mapping strategy.
55 | return DefaultResolver.ResolveKeyProperties(type);
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/AA.Dapper/FluentMap.Dommel/Resolvers/DommelPropertyResolver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using AA.Dapper.FluentMap.Dommel.Mapping;
6 | using AA.Dapper.FluentMap.Mapping;
7 | using AA.Dapper.Dommel;
8 |
9 | namespace AA.Dapper.FluentMap.Dommel.Resolvers
10 | {
11 | ///
12 | /// Implements the interface by using the configured mapping.
13 | ///
14 | public class DommelPropertyResolver : DefaultPropertyResolver
15 | {
16 | private static readonly IPropertyResolver DefaultResolver = new DefaultPropertyResolver();
17 |
18 | ///
19 | protected override IEnumerable FilterComplexTypes(IEnumerable properties)
20 | {
21 | foreach (var propertyInfo in properties)
22 | {
23 | var type = propertyInfo.PropertyType;
24 | type = Nullable.GetUnderlyingType(type) ?? type;
25 |
26 | if (type.GetTypeInfo().IsPrimitive || type.GetTypeInfo().IsEnum || PrimitiveTypes.Contains(type))
27 | {
28 | yield return propertyInfo;
29 | }
30 | }
31 | }
32 |
33 | ///
34 | public override IEnumerable ResolveProperties(Type type)
35 | {
36 | IEntityMap entityMap;
37 | if (FluentMapper.EntityMaps.TryGetValue(type, out entityMap))
38 | {
39 | foreach (var property in FilterComplexTypes(type.GetProperties()))
40 | {
41 | // Determine whether the property should be ignored.
42 | var propertyMap = entityMap.PropertyMaps.FirstOrDefault(p => p.PropertyInfo.Name == property.Name);
43 | if (propertyMap == null || !propertyMap.Ignored)
44 | {
45 | var dommelPropertyMap = propertyMap as DommelPropertyMap;
46 | if (dommelPropertyMap != null)
47 | {
48 | yield return new ColumnPropertyInfo(property, isKey: dommelPropertyMap.Key);
49 | }
50 | else
51 | {
52 | yield return new ColumnPropertyInfo(property);
53 | }
54 | }
55 | }
56 | }
57 | else
58 | {
59 | foreach (var property in DefaultResolver.ResolveProperties(type))
60 | {
61 | yield return property;
62 | }
63 | }
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/AA.Dapper/FluentMap.Dommel/Resolvers/DommelTableNameResolver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using AA.Dapper.FluentMap.Dommel.Mapping;
3 | using AA.Dapper.FluentMap.Mapping;
4 | using AA.Dapper.Dommel;
5 |
6 |
7 | namespace AA.Dapper.FluentMap.Dommel.Resolvers
8 | {
9 | ///
10 | /// Implements the interface by using the configured mapping.
11 | ///
12 | public class DommelTableNameResolver : ITableNameResolver
13 | {
14 | private static readonly ITableNameResolver DefaultResolver = new DefaultTableNameResolver();
15 |
16 | ///
17 | public string ResolveTableName(Type type)
18 | {
19 | IEntityMap entityMap;
20 | if (FluentMapper.EntityMaps.TryGetValue(type, out entityMap))
21 | {
22 | var mapping = entityMap as IDommelEntityMap;
23 |
24 | if (mapping != null)
25 | {
26 | return mapping.TableName;
27 | }
28 | }
29 |
30 | return DefaultResolver.ResolveTableName(type);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/AA.Dapper/FluentMap/Configuration/FluentMapConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.ComponentModel;
4 | using AA.Dapper.FluentMap.Conventions;
5 | using AA.Dapper.FluentMap.Mapping;
6 |
7 | namespace AA.Dapper.FluentMap.Configuration
8 | {
9 | ///
10 | /// Defines methods for configuring Dapper.FluentMap.
11 | ///
12 | public class FluentMapConfiguration
13 | {
14 | ///
15 | /// Adds the specified to the configuration of Dapper.FluentMap.
16 | ///
17 | /// The type argument of the entity.
18 | ///
19 | /// An instance of the interface containing the
20 | /// entity mapping configuration.
21 | ///
22 | public void AddMap(IEntityMap mapper) where TEntity : class
23 | {
24 | if (FluentMapper.EntityMaps.TryAdd(typeof(TEntity), mapper))
25 | {
26 | FluentMapper.AddTypeMap();
27 | }
28 | else
29 | {
30 | throw new InvalidOperationException($"Adding entity map for type '{typeof(TEntity)}' failed. The type already exists. Current entity maps: " + string.Join(", ", FluentMapper.EntityMaps.Select(e => e.Key.ToString())));
31 | }
32 | }
33 |
34 | ///
35 | /// Adds the specified to the configuration of Dapper.FluentMap.
36 | ///
37 | /// The type of the convention.
38 | ///
39 | /// An instance of
40 | /// which allows configuration of the convention.
41 | ///
42 | public FluentConventionConfiguration AddConvention() where TConvention : Convention, new()
43 | {
44 | return new FluentConventionConfiguration(new TConvention());
45 | }
46 |
47 | #region EditorBrowsableStates
48 | ///
49 | [EditorBrowsable(EditorBrowsableState.Never)]
50 | public override string ToString()
51 | {
52 | return base.ToString();
53 | }
54 |
55 | ///
56 | [EditorBrowsable(EditorBrowsableState.Never)]
57 | public override bool Equals(object obj)
58 | {
59 | return base.Equals(obj);
60 | }
61 |
62 | ///
63 | [EditorBrowsable(EditorBrowsableState.Never)]
64 | public override int GetHashCode()
65 | {
66 | return base.GetHashCode();
67 | }
68 |
69 | ///
70 | [EditorBrowsable(EditorBrowsableState.Never)]
71 | public new Type GetType()
72 | {
73 | return base.GetType();
74 | }
75 | #endregion
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/AA.Dapper/FluentMap/Conventions/PropertyConventionConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Reflection;
5 |
6 | namespace AA.Dapper.FluentMap.Conventions
7 | {
8 | ///
9 | /// Represents the configuration for a convention.
10 | ///
11 | public class PropertyConventionConfiguration
12 | {
13 | ///
14 | /// Initializes a new instance of the class,
15 | /// allowing configuration for a convention.
16 | ///
17 | public PropertyConventionConfiguration()
18 | {
19 | PropertyPredicates = new List>();
20 | }
21 |
22 | internal IList> PropertyPredicates { get; }
23 |
24 | internal ConventionPropertyConfiguration PropertyConfiguration { get; private set; }
25 |
26 | ///
27 | /// Filters the properties that this convention applies to based on a predicate.
28 | ///
29 | /// A function to test each property for a condition.
30 | /// The same instance of .
31 | public PropertyConventionConfiguration Where(Func predicate)
32 | {
33 | PropertyPredicates.Add(predicate);
34 | return this;
35 | }
36 |
37 | ///
38 | /// Configures the properties that this convention applies to.
39 | ///
40 | ///
41 | /// An action that performs configuration against
42 | /// .
43 | ///
44 | public void Configure(Action configure)
45 | {
46 | var config = new ConventionPropertyConfiguration();
47 | PropertyConfiguration = config;
48 | configure(config);
49 | }
50 |
51 | #region EditorBrowsableStates
52 | ///
53 | [EditorBrowsable(EditorBrowsableState.Never)]
54 | public override string ToString()
55 | {
56 | return base.ToString();
57 | }
58 |
59 | ///
60 | [EditorBrowsable(EditorBrowsableState.Never)]
61 | public override bool Equals(object obj)
62 | {
63 | return base.Equals(obj);
64 | }
65 |
66 | ///
67 | [EditorBrowsable(EditorBrowsableState.Never)]
68 | public override int GetHashCode()
69 | {
70 | return base.GetHashCode();
71 | }
72 |
73 | ///
74 | [EditorBrowsable(EditorBrowsableState.Never)]
75 | public new Type GetType()
76 | {
77 | return base.GetType();
78 | }
79 | #endregion
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/AA.Dapper/FluentMap/FluentMapper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Concurrent;
3 | using System.Collections.Generic;
4 | using Dapper;
5 | using AA.Dapper.FluentMap.Configuration;
6 | using AA.Dapper.FluentMap.Conventions;
7 | using AA.Dapper.FluentMap.Mapping;
8 | using AA.Dapper.FluentMap.TypeMaps;
9 |
10 | namespace AA.Dapper.FluentMap
11 | {
12 | ///
13 | /// Main entry point for Dapper.FluentMap configuration.
14 | ///
15 | public static class FluentMapper
16 | {
17 | private static readonly FluentMapConfiguration _configuration = new FluentMapConfiguration();
18 |
19 | ///
20 | /// Gets the dictionary containing the entity mapping per entity type.
21 | ///
22 | public static readonly ConcurrentDictionary EntityMaps = new ConcurrentDictionary();
23 |
24 | ///
25 | /// Gets the dictionary containing the conventions per entity type.
26 | ///
27 | public static readonly ConcurrentDictionary> TypeConventions = new ConcurrentDictionary>();
28 |
29 | ///
30 | /// Initializes Dapper.FluentMap with the specified configuration.
31 | /// This is method should be called when the application starts or when the first mapping is needed.
32 | ///
33 | /// A callback containing the configuration of Dapper.FluentMap.
34 | public static void Initialize(Action configure)
35 | {
36 | configure(_configuration);
37 | }
38 |
39 | ///
40 | /// Registers a Dapper type map using fluent mapping for the specified .
41 | ///
42 | /// The type of the entity.
43 | internal static void AddTypeMap()
44 | {
45 | SqlMapper.SetTypeMap(typeof(TEntity), new FluentMapTypeMap());
46 | }
47 |
48 | ///
49 | /// Registers a Dapper type map using fluent mapping for the specified .
50 | ///
51 | /// The type of the entity.
52 | internal static void AddTypeMap(Type entityType)
53 | {
54 | var instance = (SqlMapper.ITypeMap)Activator.CreateInstance(typeof(FluentMapTypeMap<>).MakeGenericType(entityType));
55 | SqlMapper.SetTypeMap(entityType, instance);
56 | }
57 |
58 | ///
59 | /// Registers a Dapper type map using conventions for the specified .
60 | ///
61 | /// The type of the entity.
62 | internal static void AddConventionTypeMap()
63 | {
64 | SqlMapper.SetTypeMap(typeof(TEntity), new FluentConventionTypeMap());
65 | }
66 |
67 | ///
68 | /// Registers a Dapper type map using conventions for the specified .
69 | ///
70 | /// The type of the entity.
71 | internal static void AddConventionTypeMap(Type entityType)
72 | {
73 | var instance = (SqlMapper.ITypeMap)Activator.CreateInstance(typeof(FluentConventionTypeMap<>).MakeGenericType(entityType));
74 | SqlMapper.SetTypeMap(entityType, instance);
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/AA.Dapper/FluentMap/TypeMaps/FluentTypeMap.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Reflection;
4 | using Dapper;
5 | using AA.Dapper.FluentMap.Mapping;
6 |
7 | namespace AA.Dapper.FluentMap.TypeMaps
8 | {
9 | ///
10 | /// Represents a Dapper type mapping strategy which first tries to map the type using a
11 | /// ,
12 | /// if that fails, the is used as mapping strategy.
13 | ///
14 | /// The type of the entity.
15 | public class FluentMapTypeMap : MultiTypeMap
16 | {
17 | ///
18 | /// Initializes a new instance of the class
19 | /// which uses the and
20 | /// as mapping strategies.
21 | ///
22 | public FluentMapTypeMap()
23 | : base(new CustomPropertyTypeMap(typeof(TEntity), GetPropertyInfo), new DefaultTypeMap(typeof(TEntity)))
24 | {
25 | }
26 |
27 | private static PropertyInfo GetPropertyInfo(Type type, string columnName)
28 | {
29 | var cacheKey = $"{type.FullName};{columnName}";
30 |
31 | PropertyInfo info;
32 | if (TypePropertyMapCache.TryGetValue(cacheKey, out info))
33 | {
34 | return info;
35 | }
36 |
37 | IEntityMap entityMap;
38 | if (FluentMapper.EntityMaps.TryGetValue(type, out entityMap))
39 | {
40 | var propertyMaps = entityMap.PropertyMaps;
41 |
42 | // Find the mapping for the column name.
43 | var propertyMap = propertyMaps.FirstOrDefault(m => MatchColumnNames(m, columnName));
44 |
45 | if (propertyMap != null)
46 | {
47 | if (!propertyMap.Ignored)
48 | {
49 | TypePropertyMapCache.TryAdd(cacheKey, propertyMap.PropertyInfo);
50 | return propertyMap.PropertyInfo;
51 | }
52 | #if !NETSTANDARD1_3
53 | else
54 | {
55 | var ignoredPropertyInfo = new IgnoredPropertyInfo();
56 | TypePropertyMapCache.TryAdd(cacheKey, ignoredPropertyInfo);
57 | return ignoredPropertyInfo;
58 | }
59 | #endif
60 | }
61 | }
62 |
63 | // If we get here, the property was not mapped.
64 | TypePropertyMapCache.TryAdd(cacheKey, null);
65 | return null;
66 | }
67 |
68 | private static bool MatchColumnNames(IPropertyMap map, string columnName)
69 | {
70 | var comparison = StringComparison.Ordinal;
71 | if (!map.CaseSensitive)
72 | {
73 | comparison = StringComparison.OrdinalIgnoreCase;
74 | }
75 |
76 | return string.Equals(map.ColumnName, columnName, comparison);
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/AA.Dapper/FluentMap/TypeMaps/IgnoredPropertyInfo.cs:
--------------------------------------------------------------------------------
1 | #if !NETSTANDARD1_3
2 | using System;
3 | using System.Globalization;
4 | using System.Reflection;
5 |
6 | namespace AA.Dapper.FluentMap.TypeMaps
7 | {
8 | internal class IgnoredPropertyInfo : PropertyInfo
9 | {
10 | public override Type PropertyType => throw new NotImplementedException();
11 | public override PropertyAttributes Attributes => throw new NotImplementedException();
12 | public override bool CanRead => throw new NotImplementedException();
13 | public override bool CanWrite => throw new NotImplementedException();
14 | public override string Name => throw new NotImplementedException();
15 | public override Type DeclaringType => throw new NotImplementedException();
16 | public override ParameterInfo[] GetIndexParameters() => throw new NotImplementedException();
17 | public override Type ReflectedType => throw new NotImplementedException();
18 | public override MethodInfo[] GetAccessors(bool nonPublic) => throw new NotImplementedException();
19 | public override object[] GetCustomAttributes(bool inherit) => throw new NotImplementedException();
20 | public override object[] GetCustomAttributes(Type attributeType, bool inherit) => throw new NotImplementedException();
21 | public override MethodInfo GetGetMethod(bool nonPublic) => throw new NotImplementedException();
22 | public override MethodInfo GetSetMethod(bool nonPublic) => throw new NotImplementedException();
23 | public override bool IsDefined(Type attributeType, bool inherit) => throw new NotImplementedException();
24 | public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture) => throw new NotImplementedException();
25 | public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture) => throw new NotImplementedException();
26 | }
27 | }
28 | #endif
--------------------------------------------------------------------------------
/AA.Dapper/FluentMap/Utils/DictionaryExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace AA.Dapper.FluentMap.Utils
4 | {
5 | internal static class DictionaryExtensions
6 | {
7 | internal static void AddOrUpdate(this IDictionary> dict, TKey key, TValue value)
8 | {
9 | if (dict.ContainsKey(key))
10 | {
11 | dict[key].Add(value);
12 | }
13 | else
14 | {
15 | dict.Add(key, new List { value });
16 | }
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/AA.Dapper/FluentMap/Utils/ReflectionHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Linq.Expressions;
4 | using System.Reflection;
5 |
6 | namespace AA.Dapper.FluentMap.Utils
7 | {
8 | ///
9 | /// Provides helper methods for reflection operations.
10 | ///
11 | public static class ReflectionHelper
12 | {
13 | ///
14 | /// Returns the for the specified lamba expression.
15 | ///
16 | /// A lamba expression containing a MemberExpression.
17 | /// A object for the member in the specified lambda expression.
18 | public static MemberInfo GetMemberInfo(LambdaExpression lambda)
19 | {
20 | Expression expr = lambda;
21 | while (true)
22 | {
23 | switch (expr.NodeType)
24 | {
25 | case ExpressionType.Lambda:
26 | expr = ((LambdaExpression)expr).Body;
27 | break;
28 |
29 | case ExpressionType.Convert:
30 | expr = ((UnaryExpression)expr).Operand;
31 | break;
32 |
33 | case ExpressionType.MemberAccess:
34 | var memberExpression = (MemberExpression)expr;
35 | var member = memberExpression.Member;
36 | Type paramType;
37 |
38 | while (memberExpression != null)
39 | {
40 | paramType = memberExpression.Type;
41 |
42 | // Find the member on the base type of the member type
43 | // E.g. EmailAddress.Value
44 | var baseMember = paramType.GetMembers().FirstOrDefault(m => m.Name == member.Name);
45 | if (baseMember != null)
46 | {
47 | // Don't use the base type if it's just the nullable type of the derived type
48 | // or when the same member exists on a different type
49 | // E.g. Nullable -> decimal
50 | // or: SomeType { string Length; } -> string.Length
51 | if (baseMember is PropertyInfo baseProperty && member is PropertyInfo property)
52 | {
53 | if (baseProperty.DeclaringType == property.DeclaringType &&
54 | baseProperty.PropertyType != Nullable.GetUnderlyingType(property.PropertyType))
55 | {
56 | return baseMember;
57 | }
58 | }
59 | else
60 | {
61 | return baseMember;
62 | }
63 | }
64 |
65 | memberExpression = memberExpression.Expression as MemberExpression;
66 | }
67 |
68 | // Make sure we get the property from the derived type.
69 | paramType = lambda.Parameters[0].Type;
70 | return paramType.GetMember(member.Name)[0];
71 |
72 | default:
73 | return null;
74 | }
75 | }
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/AA.Dapper/IDapperContext.cs:
--------------------------------------------------------------------------------
1 | using AA.Dapper.Util;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Data;
5 | using System.Text;
6 |
7 | namespace AA.Dapper
8 | {
9 | public interface IDapperContext : IDisposable
10 | {
11 | IDbTransaction dbTransaction { get; }
12 | IDbConnection Connection { get; }
13 | IDbTransaction BeginTransaction(IsolationLevel isolationLevel = IsolationLevel.RepeatableRead);
14 | void Commit();
15 | void RollBack();
16 | DataBase DataBase { get; }
17 |
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/AA.Dapper/IDbProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Data.Common;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace AA.Dapper
9 | {
10 | public interface IDbProvider
11 | {
12 | void Initialize();
13 |
14 | ///
15 | /// Returns a new connection object to communicate with the database.
16 | ///
17 | /// A new
18 | DbConnection CreateConnection();
19 |
20 | ///
21 | /// Connection string used to create connections.
22 | ///
23 | string ConnectionString { set; get; }
24 |
25 | DbMetadata Metadata { get; }
26 |
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/AA.Dapper/TimeSpanParseRuleAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace AA.Dapper
8 | {
9 | ///
10 | /// Attribute to use with public properties that
11 | /// can be set with Quartz configuration. Attribute can be used to advice
12 | /// parsing to use correct type of time span (milliseconds, seconds, minutes, hours)
13 | /// as it may depend on property.
14 | ///
15 | /// Marko Lahma (.NET)
16 | ///
17 | public class TimeSpanParseRuleAttribute : Attribute
18 | {
19 | ///
20 | /// Initializes a new instance of the class.
21 | ///
22 | /// The rule.
23 | public TimeSpanParseRuleAttribute(TimeSpanParseRule rule)
24 | {
25 | Rule = rule;
26 | }
27 |
28 | ///
29 | /// Gets the rule.
30 | ///
31 | /// The rule.
32 | public TimeSpanParseRule Rule { get; }
33 | }
34 |
35 | ///
36 | /// Possible parse rules for s.
37 | ///
38 | public enum TimeSpanParseRule
39 | {
40 | ///
41 | ///
42 | ///
43 | Milliseconds = 0,
44 |
45 | ///
46 | ///
47 | ///
48 | Seconds = 1,
49 |
50 | ///
51 | ///
52 | ///
53 | Minutes = 2,
54 |
55 | ///
56 | ///
57 | ///
58 | Hours = 3,
59 |
60 | ///
61 | ///
62 | ///
63 | Days = 3
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/AA.Dapper/Util/Configuration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.Specialized;
4 | using System.Configuration;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace AA.Dapper.Util
10 | {
11 | internal static class Configuration
12 | {
13 |
14 |
15 | internal static NameValueCollection GetSection(string sectionName)
16 | {
17 | try
18 | {
19 | return (NameValueCollection)ConfigurationManager.GetSection(sectionName);
20 | }
21 | catch (Exception e)
22 | {
23 | // log.Warn("could not read configuration using ConfigurationManager.GetSection: " + e.Message);
24 | return null;
25 | }
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/AA.Dapper/Util/DataBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Data;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using AA.FrameWork.Domain;
7 | using Dapper;
8 | namespace AA.Dapper.Util
9 | {
10 | public class DataBase
11 | {
12 | private IDapperContext dapperContext;
13 | public DataBase(DapperContext dapperContext)
14 | {
15 | this.dapperContext = dapperContext;
16 | }
17 | public int Execute(string sql, object param = null)
18 | {
19 | return dapperContext.Connection.Execute(sql, param, dapperContext.dbTransaction);
20 | }
21 |
22 | public Task ExecuteAsync(string sql, object param = null)
23 | {
24 | return dapperContext.Connection.ExecuteAsync(sql, param, dapperContext.dbTransaction);
25 | }
26 |
27 | public T ExecuteScalar(string sql, object param = null)
28 | {
29 | return dapperContext.Connection.ExecuteScalar(sql, param, dapperContext.dbTransaction);
30 | }
31 |
32 | public Task ExecuteScalarAsync(string sql, object param = null)
33 | {
34 | return dapperContext.Connection.ExecuteScalarAsync(sql, param, dapperContext.dbTransaction);
35 | }
36 |
37 | public IEnumerable Query(string sql, object param = null)
38 | {
39 | return dapperContext.Connection.Query(sql, param, dapperContext.dbTransaction);
40 | }
41 |
42 | public Task> QueryAsync(string sql, object param = null)
43 | {
44 | return dapperContext.Connection.QueryAsync(sql, param, dapperContext.dbTransaction);
45 | }
46 |
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/AA.Dapper/Util/DynamicExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Linq.Expressions;
5 | using System.Text;
6 |
7 | namespace AA.Dapper.Util
8 | {
9 | public static class DynamicWhereExpression
10 | {
11 |
12 | public static Expression> Init() { return f => true; }
13 |
14 | public static Expression> And(this Expression> left, Expression> right)
15 | {
16 | if (left == null)
17 | {
18 | return right;
19 | }
20 |
21 | var invokeExpression = Expression.Invoke(right, left.Parameters.Cast());
22 | return (Expression.Lambda>(Expression.AndAlso(left.Body, invokeExpression), left.Parameters));
23 | }
24 |
25 | public static Expression> Or(this Expression> left, Expression> right)
26 | {
27 | if (left == null)
28 | {
29 | return right;
30 | }
31 |
32 | var invokeExpression = Expression.Invoke(right, left.Parameters.Cast());
33 | return (Expression.Lambda>(Expression.OrElse(left.Body, invokeExpression), left.Parameters));
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/AA.Dapper/Util/IDbConnectionManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Data.Common;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace AA.Dapper.Util
9 | {
10 | ///
11 | /// Manages a collection of IDbProviders, and provides transparent access
12 | /// to their database.
13 | ///
14 | public interface IDbConnectionManager
15 | {
16 | ///
17 | /// Shuts down database connections from the data source with the given name,
18 | /// if applicable for the underlying provider.
19 | ///
20 | void Shutdown(string dataSourceName);
21 |
22 | ///
23 | /// Get a database connection from the data source with the given name.
24 | ///
25 | DbConnection GetConnection(string dataSourceName);
26 |
27 | ///
28 | /// Returns meta data for data source with the given name.
29 | ///
30 | DbMetadata GetDbMetadata(string dataSourceName);
31 |
32 | ///
33 | /// Gets db provider for data source with the given name.
34 | ///
35 | IDbProvider GetDbProvider(string dataSourceName);
36 |
37 | ///
38 | /// Adds a connection provider to data source with the given name.
39 | ///
40 | void AddConnectionProvider(string dataSourceName, IDbProvider provider);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/AA.FrameWork.Tests.Unit.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0;netcoreapp3.1
5 |
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | Always
35 |
36 |
37 | Always
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/AutoMapper/AutoMapperTest.cs:
--------------------------------------------------------------------------------
1 | using AA.AutoMapper;
2 | using AutoMapper;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 | using Xunit;
7 | using AA.FrameWork.Extensions;
8 | namespace AA.FrameWork.Tests.Unit.AutoMapper
9 | {
10 |
11 | public class AutoMapperTest
12 | {
13 | private void Init()
14 | {
15 | var mapperConfig = new WebMapperConfigurations();
16 | AutoMapperConfiguration.Init(new List> { mapperConfig.GetConfiguration() });
17 | ObjectMapping.ObjectMapManager.ObjectMapper = new AutoMapperObjectMapper();
18 | }
19 |
20 | [Fact]
21 | public void TestMap()
22 | {
23 | //init
24 | Init();
25 | UserVm userVm = new UserVm { Id = 1, Name = "成天" ,Remark="微信公众号:dotNet知音"};
26 | var userDto = userVm.MapTo();
27 | //var userDto2 = userVm.MapTo();
28 |
29 | }
30 |
31 |
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/AutoMapper/UserVm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace AA.FrameWork.Tests.Unit.AutoMapper
6 | {
7 | //viewModel
8 | public class UserVm
9 | {
10 | public int Id { get; set; }
11 | public string Name { get; set; }
12 | public string Remark { get; set; }
13 | }
14 |
15 | //dto
16 | public class UserInput
17 | {
18 | public int Id { get; set; }
19 | public string Name { get; set; }
20 | public string Remark { get; set; }
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/AutoMapper/WebMapperConfigurations.cs:
--------------------------------------------------------------------------------
1 | using AA.AutoMapper;
2 | using AutoMapper;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace AA.FrameWork.Tests.Unit.AutoMapper
8 | {
9 | public class WebMapperConfigurations : IMapperConfiguration
10 | {
11 | public int Order { get { return 0; } }
12 |
13 | public Action GetConfiguration()
14 | {
15 | Action action = cfg =>
16 | {
17 | cfg.CreateMap();
18 | };
19 | return action;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/Log4Net/log4net.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/Log4Net/log4netTest.cs:
--------------------------------------------------------------------------------
1 | using AA.FrameWork.Logging;
2 | using AA.Log4Net;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 | using Xunit;
7 |
8 | namespace AA.FrameWork.Tests.Unit.Log4Net
9 | {
10 | public class log4netTest
11 | {
12 |
13 | [Fact]
14 | public void TestLog4net()
15 | {
16 | Log4NetLogger.Use("Log4Net/log4net.config");
17 | ILog log = Logger.Get(typeof(log4netTest));
18 | log.Debug("test log record");
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/NLog/NLogTest.cs:
--------------------------------------------------------------------------------
1 | using AA.FrameWork.Logging;
2 | using AA.NLogging;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 | using Xunit;
7 |
8 | namespace AA.FrameWork.Tests.Unit.NLog
9 | {
10 | public class NLogTest
11 | {
12 | [Fact]
13 | public void TestNLog()
14 | {
15 | NLogLogger.Use("NLog/nlog.config");
16 | ILog log = Logger.Get(typeof(NLogTest));
17 | log.Debug("test nlog record");
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/NLog/nlog.config:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/RabbitMQ/ServiceBus/Consumer.cs:
--------------------------------------------------------------------------------
1 | using AA.ServiceBus;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 | using MassTransit;
6 | using System.Threading.Tasks;
7 | using AA.FrameWork.Tests.Unit.RabbitMQ.ServiceBus.meesageContracts;
8 | using Xunit;
9 | using AA.Log4Net;
10 | using AA.FrameWork.Logging;
11 |
12 | namespace AA.FrameWork.Tests.Unit.RabbitMQ.ServiceBus
13 | {
14 | public class Consumer
15 | {
16 | [Fact]
17 | public void TestConsumer()
18 | {
19 | Log4NetLogger.Use("Log4Net/log4net.config");
20 | string rabbitMqUri = "rabbitmq://localhost:5672";
21 | string rabbitMqUserName = "";
22 | string rabbitMqPassword = "";
23 | string queueName = "order.queue";
24 |
25 | var busControl = ServiceBusManager.Instance.UseRabbitMq(rabbitMqUri, rabbitMqUserName, rabbitMqPassword)
26 | .RegisterConsumer(queueName)
27 | .RegisterConsumer(null)
28 | .Build();
29 | busControl.Start();
30 |
31 | }
32 | }
33 |
34 | public class OrderSubmittedEventConsumer : IConsumer
35 | {
36 | public async Task Consume(ConsumeContext context)
37 | {
38 | var @event = context.Message;
39 |
40 | var result = $"OrderSubmittedEvent {@event.Id.ToString()}";
41 | ILog log = Logger.Get(typeof(OrderSubmittedEventConsumer));
42 | log.Debug(result);
43 | //do somethings...
44 | }
45 | }
46 |
47 |
48 | public class SubmitOrderCommandConsumer : IConsumer
49 | {
50 | public async Task Consume(ConsumeContext context)
51 | {
52 | var command = context.Message;
53 |
54 | var result = $"CreateFooCommand {command.Id.ToString()}";
55 | ILog log = Logger.Get(typeof(SubmitOrderCommandConsumer));
56 | log.Debug(result);
57 | //do somethings...
58 | }
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/RabbitMQ/ServiceBus/Producer.cs:
--------------------------------------------------------------------------------
1 | using AA.FrameWork.Tests.Unit.RabbitMQ.ServiceBus.meesageContracts;
2 | using AA.ServiceBus;
3 | using MassTransit;
4 | using MassTransit.Util;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Text;
8 | using Xunit;
9 |
10 | namespace AA.FrameWork.Tests.Unit.RabbitMQ.ServiceBus
11 | {
12 | public class Producer
13 | {
14 | [Fact]
15 | public void TestProducer()
16 | {
17 | string rabbitMqUri = "rabbitmq://localhost:5672";
18 | string rabbitMqUserName = "";
19 | string rabbitMqPassword = "";
20 |
21 |
22 | PulishEvent(rabbitMqUri, rabbitMqUserName, rabbitMqPassword);
23 | SendCommand(rabbitMqUri, rabbitMqUserName, rabbitMqPassword);
24 | }
25 |
26 |
27 | private void PulishEvent(string rabbitMqUri, string rabbitMqUserName, string rabbitMqPassword)
28 | {
29 | IBusControl busControl = ServiceBusManager.Instance.UseRabbitMq(rabbitMqUri, rabbitMqUserName, rabbitMqPassword)
30 | .BuildEventProducer();
31 |
32 | TaskUtil.Await(busControl.Publish(new
33 | {
34 | Id = 1
35 | }));
36 | }
37 |
38 | private void SendCommand(string rabbitMqUri, string rabbitMqUserName, string rabbitMqPassword)
39 | {
40 | string queueName = "order.queue";
41 |
42 | ISendEndpoint busControl = ServiceBusManager.Instance.UseRabbitMq(rabbitMqUri, rabbitMqUserName, rabbitMqPassword)
43 | .BuildCommandProducer(queueName);
44 |
45 | TaskUtil.Await(busControl.Send(new
46 | {
47 | Id = 10
48 | }));
49 | }
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/RabbitMQ/ServiceBus/meesageContracts/OrderSubmitted.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace AA.FrameWork.Tests.Unit.RabbitMQ.ServiceBus.meesageContracts
6 | {
7 | public interface OrderSubmitted
8 | {
9 | long Id { get; set; }
10 | decimal OrderPrice { get; set; }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/RabbitMQ/ServiceBus/meesageContracts/SubmitOrder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace AA.FrameWork.Tests.Unit.RabbitMQ.ServiceBus.meesageContracts
6 | {
7 | public interface SubmitOrder
8 | {
9 | long Id { get; set; }
10 | Decimal OrderPrice { get; set; }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/dapper/AADapperContext.cs:
--------------------------------------------------------------------------------
1 | using AA.Dapper;
2 | using System.Collections.Specialized;
3 |
4 | namespace AA.FrameWork.Tests.Unit.dapper
5 | {
6 | //public class AADapperContext : DapperContext
7 | //{
8 | // public AADapperContext() : base(new NameValueCollection()
9 | // {
10 | // ["aa.dataSource.AaCenter.connectionString"] = "Data Source =.; Initial Catalog = AaCenter;User ID = sa; Password = lee2018;",
11 | // ["aa.dataSource.AaCenter.provider"] = "SqlServer"
12 | // })
13 | // { }
14 | //}
15 | }
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/dapper/AADapperRepositoryMysqlTest.cs:
--------------------------------------------------------------------------------
1 | using AA.Dapper;
2 | using AA.Dapper.Advanced;
3 | using AA.Dapper.Repositories;
4 | using AA.FrameWork.Tests.Unit.dapper.Entity;
5 | using AA.FrameWork.Tests.Unit.dapper.Init;
6 | using AA.FrameWork.Tests.Unit.dapper.Repository;
7 | using System;
8 | using System.Collections.Generic;
9 | using System.Collections.Specialized;
10 | using System.Text;
11 | using Xunit;
12 |
13 | namespace AA.FrameWork.Tests.Unit.dapper
14 | {
15 | public class AADapperRepositoryMysqlTest
16 | {
17 | /*
18 | AA.dapper 使用步骤
19 |
20 |
21 | 1.定义领域model
22 |
23 | 2.定义数据表映射关系
24 |
25 |
26 |
27 | */
28 | //IDapperContext dapperContext = new AADapperContext(); 推荐使用DI
29 | public static IDapperContext dapperContext = new DapperContext();
30 | IUserRepository userRepository = new UserRepository(dapperContext);
31 | public AADapperRepositoryMysqlTest()
32 | {
33 | DbEntityMap.InitMapCfgs();
34 | //init datasourse
35 | IDbDatasource dbDatasource = new DbDataSource();
36 | dbDatasource.Init(new NameValueCollection()
37 | {
38 | ["aa.dataSource.master_demo.connectionString"] = "Data Source =localhost; Initial Catalog = demo;User ID = root; Password = cheng@123;",
39 | ["aa.dataSource.master_demo.provider"] = "MySql"
40 |
41 | });
42 |
43 | //dbDatasource.Init(new NameValueCollection()
44 | //{
45 | // ["aa.dataSource.slave_AaCenter.connectionString"] = "Data Source =.; Initial Catalog = AaCenterS1;User ID = sa; Password = lee2018;",
46 | // ["aa.dataSource.slave_AaCenter.provider"] = "SqlServer"
47 | //});
48 |
49 |
50 | }
51 | ///
52 | /// Insert
53 | ///
54 | [Fact]
55 | public void TextInsert()
56 | {
57 |
58 | var user = new User()
59 | {
60 | Name = "李四",
61 | Age = 30
62 | };
63 | var result = userRepository.Insert(user);
64 | }
65 |
66 | ///
67 | /// Get
68 | ///
69 | [Fact]
70 | public void TextGet()
71 | {
72 | try
73 | {
74 | var users = userRepository.GetAll();
75 | }
76 | catch (Exception ex) { }
77 |
78 |
79 | var b = 0;
80 |
81 | }
82 |
83 |
84 |
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/dapper/Advanced/DbDataSourceText.cs:
--------------------------------------------------------------------------------
1 | using AA.Dapper;
2 | using AA.Dapper.Advanced;
3 | using AA.FrameWork.Tests.Unit.dapper.Init;
4 | using AADemo.DataAccess.Repository;
5 | using AADemo.Domain.Repository;
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Collections.Specialized;
9 | using System.Text;
10 | using Xunit;
11 | using System.Linq;
12 |
13 | namespace AA.FrameWork.Tests.Unit.dapper.Advanced
14 | {
15 |
16 | public class DbDataSourceText
17 | {
18 | [Fact]
19 | public void TextDapperContext()
20 | {
21 | DbEntityMap.InitMapCfgs();
22 | IDbDatasource dbDatasource = new DbDataSource();
23 | dbDatasource.Init(new NameValueCollection()
24 | {
25 | ["aa.dataSource.master_AaCenter.connectionString"] = "Data Source =.; Initial Catalog = AaCenter;User ID = sa; Password = lee2018;",
26 | ["aa.dataSource.master_AaCenter.provider"] = "SqlServer"
27 | });
28 |
29 | dbDatasource.Init(new NameValueCollection()
30 | {
31 | ["aa.dataSource.slave_AaCenter.connectionString"] = "Data Source =.; Initial Catalog = AaCenterS1;User ID = sa; Password = lee2018;",
32 | ["aa.dataSource.slave_AaCenter.provider"] = "SqlServer"
33 | });
34 |
35 |
36 | DbContextHolder.SetDbSourceMode("slave");
37 | IDapperContext dapperContext = new DapperContext();
38 |
39 | IUserInfoRepository _userInforepository = new UserInfoRepository(dapperContext);
40 |
41 | var list= _userInforepository.GetAll().ToList();
42 | //IVillageRepository villageRepository = new VillageRepository();
43 | //villageRepository.Insert(new Village
44 | //{
45 | // Id = Guid.NewGuid(),
46 | // VillageName = "aa",
47 | // GmtCreate = DateTime.Now,
48 | // GmtModified = DateTime.Now
49 | //});
50 |
51 |
52 | //var model = villageRepository.Get(new Guid("6D880321-DB17-4B32-9F0A-CE9F3F25AA01"));
53 | //model.VillageName = "bbb";
54 | //villageRepository.Update(model);
55 |
56 | ////var obj = _userInforepository.Insert(new UserInfo()
57 | ////{
58 | //// RealName = "111",
59 | //// UserName = "bbb",
60 | //// GmtCreate=DateTime.Now,
61 | //// LastLoginDate=DateTime.Now,
62 | //// GmtModified=DateTime.Now
63 | ////});
64 | // var users = _userInforepository.QueryAll();
65 | //var userList = _userInforepository.From(sql =>
66 | // sql.Select()
67 | // .Where(p => p.RealName.Contains("成"))
68 | // .OrderBy(x => x.SysNo)
69 | // .Page(1, 20)
70 | // );
71 |
72 | //var count = userList.ToList().Count();
73 |
74 | ////动态where
75 | //Expression> expression = p => p.RealName == "成天";
76 | //var where = DynamicWhereExpression.Init();
77 |
78 | //where = where.And(x => x.RealName == "成天");
79 | //var dynamicUsers = _userInforepository.From(sql =>
80 | // sql.Select()
81 | // .Where(where)
82 | // .OrderBy(x => x.SysNo)
83 | // .Page(1, 20)
84 | //);
85 | //var count2 = dynamicUsers.ToList().Count();
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/dapper/Entity/User.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace AA.FrameWork.Tests.Unit.dapper.Entity
6 | {
7 | public class User
8 | {
9 | public long Id { get; set; }
10 | public string Name { get; set; }
11 | public int Age { get; set; }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/dapper/Entity/UserInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using AA.FrameWork.Domain;
5 | namespace AA.Dapper.Test
6 | {
7 | public class UserInfo
8 | {
9 | ///
10 | /// SysNo
11 | ///
12 | public long SysNo
13 | {
14 | get;
15 | set;
16 | }
17 |
18 | ///
19 | /// UserName
20 | ///
21 | public string UserName
22 | {
23 | get;
24 | set;
25 | }
26 |
27 | ///
28 | /// RealName
29 | ///
30 | public string RealName
31 | {
32 | get;
33 | set;
34 | }
35 |
36 | ///
37 | /// Pwd
38 | ///
39 | public string Pwd
40 | {
41 | get;
42 | set;
43 | }
44 |
45 | ///
46 | /// UserType
47 | ///
48 | public int UserType
49 | {
50 | get;
51 | set;
52 | }
53 |
54 | ///
55 | /// Status
56 | ///
57 | public int Status
58 | {
59 | get;
60 | set;
61 | }
62 |
63 | ///
64 | /// Mobile
65 | ///
66 | public string Mobile
67 | {
68 | get;
69 | set;
70 | }
71 |
72 | ///
73 | /// Email
74 | ///
75 | public string Email
76 | {
77 | get;
78 | set;
79 | }
80 |
81 | ///
82 | /// QQ
83 | ///
84 | public string QQ
85 | {
86 | get;
87 | set;
88 | }
89 |
90 | ///
91 | /// SuperUser
92 | ///
93 | public bool SuperUser
94 | {
95 | get;
96 | set;
97 | }
98 |
99 | ///
100 | /// CreateDate
101 | ///
102 | public DateTime GmtCreate
103 | {
104 | get;
105 | set;
106 | }
107 |
108 | ///
109 | /// LastLoginDate
110 | ///
111 | public DateTime LastLoginDate
112 | {
113 | get;
114 | set;
115 | }
116 |
117 | ///
118 | /// TenantId
119 | ///
120 | public Guid TenantId
121 | {
122 | get;
123 | set;
124 | }
125 |
126 | public DateTime GmtModified { get; set; }
127 |
128 | public string UserPic { get; set; }
129 |
130 |
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/dapper/Entity/Village.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.DataAnnotations.Schema;
4 | using System.Text;
5 |
6 | namespace AA.Dapper.Test
7 | {
8 | public class Village
9 | {
10 |
11 | ///
12 | ///
13 | ///
14 | [DatabaseGenerated(DatabaseGeneratedOption.None)]
15 | public System.Guid Id
16 | {
17 | get;
18 | set;
19 | }
20 | ///
21 | ///
22 | ///
23 | public string VillageName
24 | {
25 | get;
26 | set;
27 | }
28 | ///
29 | ///
30 | ///
31 | public string VillageAddress
32 | {
33 | get;
34 | set;
35 | }
36 | ///
37 | ///
38 | ///
39 | public string Province
40 | {
41 | get;
42 | set;
43 | }
44 | ///
45 | ///
46 | ///
47 | public string City
48 | {
49 | get;
50 | set;
51 | }
52 | ///
53 | ///
54 | ///
55 | public string Area
56 | {
57 | get;
58 | set;
59 | }
60 | ///
61 | ///
62 | ///
63 | public string ProvinceCode
64 | {
65 | get;
66 | set;
67 | }
68 | ///
69 | ///
70 | ///
71 | public string CityCode
72 | {
73 | get;
74 | set;
75 | }
76 | ///
77 | ///
78 | ///
79 | public string AreaCode
80 | {
81 | get;
82 | set;
83 | }
84 | ///
85 | ///
86 | ///
87 | public System.DateTime GmtCreate
88 | {
89 | get;
90 | set;
91 | }
92 | ///
93 | ///
94 | ///
95 | public System.DateTime GmtModified
96 | {
97 | get;
98 | set;
99 | }
100 | ///
101 | ///
102 | ///
103 | public string Contact
104 | {
105 | get;
106 | set;
107 | }
108 | ///
109 | ///
110 | ///
111 | public string ContactTel
112 | {
113 | get;
114 | set;
115 | }
116 |
117 | }
118 | }
119 |
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/dapper/EntityMap/UserInfoMap.cs:
--------------------------------------------------------------------------------
1 | using AA.Dapper.FluentMap.Dommel.Mapping;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 |
7 | namespace AA.Dapper.Test
8 | {
9 | public class UserInfoMap : DommelEntityMap
10 | {
11 | public UserInfoMap()
12 | {
13 | ToTable("Sys_UserInfo");//映射具体的表名
14 | Map(p => p.SysNo).IsKey().IsIdentity();//指定主键 ,IsIdentity是否自增
15 | //Map(p=>p.UserPic).Ignore();
16 | //Map(p=>p.LastLoginDate).Ignore();
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/dapper/EntityMap/UserMap.cs:
--------------------------------------------------------------------------------
1 | using AA.Dapper.FluentMap.Dommel.Mapping;
2 | using AA.FrameWork.Tests.Unit.dapper.Entity;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace AA.FrameWork.Tests.Unit.dapper.EntityMap
8 | {
9 | public class UserMap : DommelEntityMap
10 | {
11 | public UserMap()
12 | {
13 | ToTable("user");//映射具体的表名
14 | Map(p => p.Id).IsKey().IsIdentity();//指定主键 ,IsIdentity是否自增
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/dapper/EntityMap/VillageMap.cs:
--------------------------------------------------------------------------------
1 | using AA.Dapper.FluentMap.Dommel.Mapping;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 | namespace AA.Dapper.Test
6 | {
7 | public class VillageMap:DommelEntityMap
8 | {
9 | public VillageMap()
10 | {
11 | ToTable("Village");
12 | Map(x=>x.Id).IsKey().ToColumn("Id");
13 | }
14 | }
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/dapper/Init/DbEntityMap.cs:
--------------------------------------------------------------------------------
1 | using AA.Dapper.Configuration;
2 | using AA.Dapper.FluentMap.Configuration;
3 | using AA.Dapper.Test;
4 | using AA.FrameWork.Tests.Unit.dapper.EntityMap;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Text;
8 |
9 | namespace AA.FrameWork.Tests.Unit.dapper.Init
10 | {
11 | public class DbEntityMap
12 | {
13 | public static void InitMapCfgs()
14 | {
15 | var fluentMapconfig = new List>();
16 | fluentMapconfig.Add(cfg =>
17 | {
18 | cfg.AddMap(new UserInfoMap());
19 | cfg.AddMap(new VillageMap());
20 | cfg.AddMap(new UserMap());
21 | });
22 | MapConfiguration.Init(fluentMapconfig);
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/dapper/Repository/IUserInfoRepository.cs:
--------------------------------------------------------------------------------
1 | using AA.Dapper.Repositories;
2 | using AA.Dapper.Test;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace AADemo.Domain.Repository
8 | {
9 | public interface IUserInfoRepository: IDapperRepository
10 | {
11 | IEnumerable QueryAll();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/dapper/Repository/IUserRepository.cs:
--------------------------------------------------------------------------------
1 | using AA.Dapper.Repositories;
2 | using AA.FrameWork.Tests.Unit.dapper.Entity;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace AA.FrameWork.Tests.Unit.dapper.Repository
8 | {
9 | public interface IUserRepository : IDapperRepository
10 | {
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/dapper/Repository/IVillageRepository.cs:
--------------------------------------------------------------------------------
1 | using AA.Dapper.Repositories;
2 | using AA.Dapper.Test;
3 | using AA.FrameWork.Domain;
4 |
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Text;
8 |
9 | namespace AADemo.Domain.Repository
10 | {
11 | public interface IVillageRepository: IDapperRepository
12 | {
13 |
14 | }
15 | }
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/dapper/Repository/UserInfoRepository.cs:
--------------------------------------------------------------------------------
1 | using AA.Dapper;
2 | using AA.Dapper.Repositories;
3 | using AA.Dapper.Test;
4 | using AADemo.Domain.Repository;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Text;
8 |
9 | namespace AADemo.DataAccess.Repository
10 | {
11 | public class UserInfoRepository : DapperRepository, IUserInfoRepository
12 | {
13 |
14 | public IDapperContext dapperContext;
15 | public UserInfoRepository(IDapperContext dapperContext) : base(dapperContext)
16 | {
17 | this.dapperContext = dapperContext;
18 | }
19 | public IEnumerable QueryAll()
20 | {
21 | var result = dapperContext.DataBase.Query("SELECT * from [Sys_UserInfo]");
22 | return result;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/dapper/Repository/UserRepository.cs:
--------------------------------------------------------------------------------
1 | using AA.Dapper;
2 | using AA.Dapper.Repositories;
3 | using AA.FrameWork.Tests.Unit.dapper.Entity;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Text;
7 |
8 | namespace AA.FrameWork.Tests.Unit.dapper.Repository
9 | {
10 | public class UserRepository:DapperRepository, IUserRepository
11 | {
12 | public IDapperContext dapperContext;
13 | public UserRepository(IDapperContext dapperContext) : base(dapperContext)
14 | {
15 | this.dapperContext = dapperContext;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/AA.FrameWork.Tests.Unit/dapper/Repository/VillageRepository.cs:
--------------------------------------------------------------------------------
1 | using AA.Dapper;
2 | using AA.Dapper.Repositories;
3 | using AA.Dapper.Test;
4 | using AA.FrameWork.Domain;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Text;
8 |
9 |
10 | namespace AADemo.Domain.Repository
11 | {
12 | public class VillageRepository :DapperRepository, IVillageRepository
13 | {
14 | public IDapperContext dapperContext;
15 | public VillageRepository(IDapperContext dapperContext) :base(dapperContext)
16 | {
17 | this.dapperContext = dapperContext;
18 | }
19 |
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/AA.FrameWork/AA.FrameWork.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0;netcoreapp3.1
5 | true
6 | ChengTian
7 | AA
8 | AA.Framework is built on the popular open source class library of NET Core
9 | 6.0.1
10 | https://github.com/ChengLab/AAFrameWork
11 | https://github.com/ChengLab/AAFrameWork
12 | git
13 | log4net;automapper;dapper;redis;rabbitmq
14 | 2.0.3.0
15 | 2.0.3.0
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/AA.FrameWork/AAException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.Serialization;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace AA.FrameWork
9 | {
10 | ///
11 | /// Represents errors that occur during application execution
12 | ///
13 | [Serializable]
14 | public class AAException:Exception
15 | {
16 | ///
17 | /// Initializes a new instance of the Exception class.
18 | ///
19 | public AAException()
20 | {
21 | }
22 |
23 | ///
24 | /// Initializes a new instance of the Exception class with a specified error message.
25 | ///
26 | /// The message that describes the error.
27 | public AAException(string message)
28 | : base(message)
29 | {
30 | }
31 |
32 | ///
33 | /// Initializes a new instance of the Exception class with a specified error message.
34 | ///
35 | /// The exception message format.
36 | /// The exception message arguments.
37 | public AAException(string messageFormat, params object[] args)
38 | : base(string.Format(messageFormat, args))
39 | {
40 | }
41 |
42 | ///
43 | /// Initializes a new instance of the Exception class with serialized data.
44 | ///
45 | /// The SerializationInfo that holds the serialized object data about the exception being thrown.
46 | /// The StreamingContext that contains contextual information about the source or destination.
47 | protected AAException(SerializationInfo info, StreamingContext context)
48 | : base(info, context)
49 | {
50 | }
51 |
52 |
53 | public AAException(Exception cause) : base(cause.Message, cause)
54 | {
55 | }
56 |
57 | ///
58 | /// Initializes a new instance of the Exception class with a specified error message and a reference to the inner exception that is the cause of this exception.
59 | ///
60 | /// The error message that explains the reason for the exception.
61 | /// The exception that is the cause of the current exception, or a null reference if no inner exception is specified.
62 | public AAException(string message, Exception innerException)
63 | : base(message, innerException)
64 | {
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/AA.FrameWork/Application/Services/Dto/IListResult.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace AA.FrameWork.Application.Services.Dto
4 | {
5 | ///
6 | /// This interface is defined to standardize to return a list of items to clients.
7 | ///
8 | /// Type of the items in the list
9 | public interface IListResult
10 | {
11 | ///
12 | /// List of items.
13 | ///
14 | IReadOnlyList Items { get; set; }
15 | }
16 | }
--------------------------------------------------------------------------------
/AA.FrameWork/Application/Services/Dto/IPagedResult.cs:
--------------------------------------------------------------------------------
1 | namespace AA.FrameWork.Application.Services.Dto
2 | {
3 | ///
4 | /// This interface is defined to standardize to return a page of items to clients.
5 | ///
6 | /// Type of the items in the list
7 | public interface IPagedResult : IListResult
8 | {
9 | ///
10 | /// Total count of Items.
11 | ///
12 | int TotalCount { get; set; }
13 |
14 | }
15 | }
--------------------------------------------------------------------------------
/AA.FrameWork/Application/Services/Dto/IPagedResultRequestDto.cs:
--------------------------------------------------------------------------------
1 | namespace AA.FrameWork.Application.Services.Dto
2 | {
3 | ///
4 | /// This interface is defined to standardize to request a paged result.
5 | ///
6 | public interface IPagedResultRequestDto
7 | {
8 | ///
9 | /// Skip count (beginning of the page).
10 | ///
11 | int PageIndex { get; set; }
12 | int PageSize { get; set; }
13 | }
14 | }
--------------------------------------------------------------------------------
/AA.FrameWork/Application/Services/Dto/ListResultDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace AA.FrameWork.Application.Services.Dto
5 | {
6 | ///
7 | /// Implements .
8 | ///
9 | /// Type of the items in the list
10 | [Serializable]
11 | public class ListResultDto : IListResult
12 | {
13 | ///
14 | /// List of items.
15 | ///
16 | public IReadOnlyList Items
17 | {
18 | get { return _items ?? (_items = new List()); }
19 | set { _items = value; }
20 | }
21 | private IReadOnlyList _items;
22 |
23 | ///
24 | /// Creates a new object.
25 | ///
26 | public ListResultDto()
27 | {
28 |
29 | }
30 |
31 | ///
32 | /// Creates a new object.
33 | ///
34 | /// List of items
35 | public ListResultDto(IReadOnlyList items)
36 | {
37 | Items = items;
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/AA.FrameWork/Application/Services/Dto/PagedResultDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace AA.FrameWork.Application.Services.Dto
5 | {
6 | ///
7 | /// Implements .
8 | ///
9 | /// Type of the items in the list
10 | [Serializable]
11 | public class PagedResultDto : ListResultDto, IPagedResult
12 | {
13 | ///
14 | /// Total count of Items.
15 | ///
16 | public int TotalCount { get; set; }
17 |
18 | ///
19 | /// Creates a new object.
20 | ///
21 | public PagedResultDto()
22 | {
23 |
24 | }
25 |
26 | ///
27 | /// Creates a new object.
28 | ///
29 | /// Total count of Items
30 | /// List of items in current page
31 | public PagedResultDto(int totalCount, IReadOnlyList items)
32 | : base(items)
33 | {
34 | TotalCount = totalCount;
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/AA.FrameWork/Application/Services/Dto/PagedResultRequestDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 |
4 | namespace AA.FrameWork.Application.Services.Dto
5 | {
6 | ///
7 | /// Simply implements .
8 | ///
9 | [Serializable]
10 | public class PagedResultRequestDto : IPagedResultRequestDto
11 | {
12 | public virtual int PageIndex { get; set; }
13 | public virtual int PageSize { get; set; }
14 | }
15 | }
--------------------------------------------------------------------------------
/AA.FrameWork/Domain/IEntity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace AA.FrameWork.Domain
8 | {
9 | public class BaseEntity
10 | {
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/AA.FrameWork/Domain/IPage.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace AA.FrameWork.Domain
4 | {
5 | public interface IPage where T : class
6 | {
7 | ///
8 | /// Gets or sets the count.
9 | ///
10 | ///
11 | /// The count.
12 | ///
13 | int Count { get; set; }
14 |
15 | ///
16 | /// Gets or sets the data.
17 | ///
18 | ///
19 | /// The data.
20 | ///
21 | IEnumerable Data { get; set; }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/AA.FrameWork/Domain/ISoftDelete.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace AA.FrameWork.Domain
8 | {
9 | ///
10 | /// 软删除
11 | ///
12 | public interface ISoftDelete
13 | {
14 | bool IsDeleted { get; set; }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/AA.FrameWork/Domain/Page.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace AA.FrameWork.Domain
4 | {
5 | public class Page : IPage where T : class
6 | {
7 | public int Count { get; set; }
8 |
9 | public IEnumerable Data { get; set; }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/AA.FrameWork/Domain/PageRequest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace AA.FrameWork.Domain
8 | {
9 | public class PageRequest
10 | {
11 | ///
12 | /// current page number
13 | ///
14 | public int PageIndex { get; set; }
15 | ///
16 | /// page of size
17 | ///
18 | public int PageSize { get; set; }
19 | ///
20 | /// id asc,name dec
21 | ///
22 | public string OrderFiled { get; set; }
23 | ///
24 | /// sql
25 | ///
26 | public string SqlText { get; set; }
27 | ///
28 | /// sql参数 参照dapper {}
29 | ///
30 | public object SqlParam { get; set; }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/AA.FrameWork/Engine/BaseSingleton.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace AA.FrameWork.Engine
5 | {
6 | ///
7 | /// Provides access to all "singletons" stored by .
8 | ///
9 | public class BaseSingleton
10 | {
11 | static BaseSingleton()
12 | {
13 | AllSingletons = new Dictionary();
14 | }
15 |
16 | ///
17 | /// Dictionary of type to singleton instances.
18 | ///
19 | public static IDictionary AllSingletons { get; }
20 | }
21 | }
--------------------------------------------------------------------------------
/AA.FrameWork/Engine/DependencyManagement/IDependencyRegistrar.cs:
--------------------------------------------------------------------------------
1 |
2 | using Autofac;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace AA.FrameWork.Engine
8 | {
9 | ///
10 | /// 依赖项注册器接口 Dependency registrar interface
11 | ///
12 | public interface IDependencyRegistrar
13 | {
14 | ///
15 | /// Register services and interfaces
16 | ///
17 | /// Container builder
18 | /// Type finder
19 | /// Config
20 | void Register(ContainerBuilder builder, ITypeFinder typeFinder);
21 |
22 | ///
23 | /// Gets order of this dependency registrar implementation
24 | ///
25 | int Order { get; }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/AA.FrameWork/Engine/EngineContext.cs:
--------------------------------------------------------------------------------
1 |
2 | using System.Runtime.CompilerServices;
3 |
4 | namespace AA.FrameWork.Engine
5 | {
6 | ///
7 | /// Provides access to the singleton instance of the Nop engine.
8 | ///
9 | public class EngineContext
10 | {
11 | #region Methods
12 |
13 | ///
14 | /// Create a static instance of the Nop engine.
15 | ///
16 | [MethodImpl(MethodImplOptions.Synchronized)]
17 | public static IEngine Create()
18 | {
19 | //create NopEngine as engine
20 | return Singleton.Instance ?? (Singleton.Instance = new AAEngine());
21 | }
22 |
23 | ///
24 | /// Sets the static engine instance to the supplied engine. Use this method to supply your own engine implementation.
25 | ///
26 | /// The engine to use.
27 | /// Only use this method if you know what you're doing.
28 | public static void Replace(IEngine engine)
29 | {
30 | Singleton.Instance = engine;
31 | }
32 |
33 | #endregion
34 |
35 | #region Properties
36 |
37 | ///
38 | /// Gets the singleton Nop engine used to access Nop services.
39 | ///
40 | public static IEngine Current
41 | {
42 | get
43 | {
44 | if (Singleton.Instance == null)
45 | {
46 | Create();
47 | }
48 |
49 | return Singleton.Instance;
50 | }
51 | }
52 |
53 | #endregion
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/AA.FrameWork/Engine/IEngine.cs:
--------------------------------------------------------------------------------
1 |
2 | using Microsoft.Extensions.DependencyInjection;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 | using Autofac;
7 | using Microsoft.AspNetCore.Builder;
8 |
9 | namespace AA.FrameWork.Engine
10 | {
11 | public interface IEngine
12 | {
13 | ///
14 | /// Configure HTTP request pipeline
15 | ///
16 | ///
17 | void ConfigureRequestPipeline(IApplicationBuilder application);
18 | ///
19 | /// Resolve dependency
20 | ///
21 | /// Type of resolved service
22 | /// Resolved service
23 | T Resolve() where T : class;
24 |
25 | ///
26 | /// Resolve dependency
27 | ///
28 | /// Type of resolved service
29 | /// Resolved service
30 | object Resolve(Type type);
31 |
32 | ///
33 | /// Resolve dependencies
34 | ///
35 | /// Type of resolved services
36 | /// Collection of resolved services
37 | IEnumerable ResolveAll();
38 |
39 | ///
40 | /// Resolve unregistered service
41 | ///
42 | /// Type of service
43 | /// Resolved service
44 | object ResolveUnregistered(Type type);
45 |
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/AA.FrameWork/Engine/ITypeFinder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Reflection;
4 |
5 | namespace AA.FrameWork.Engine
6 | {
7 | ///
8 | /// Classes implementing this interface provide information about types
9 | /// to various services in the Nop engine.
10 | ///
11 | public interface ITypeFinder
12 | {
13 | ///
14 | /// Find classes of type
15 | ///
16 | /// Type
17 | /// A value indicating whether to find only concrete classes
18 | /// Result
19 | IEnumerable FindClassesOfType(bool onlyConcreteClasses = true);
20 |
21 | ///
22 | /// Find classes of type
23 | ///
24 | /// Assign type from
25 | /// A value indicating whether to find only concrete classes
26 | /// Result
27 | ///
28 | IEnumerable FindClassesOfType(Type assignTypeFrom, bool onlyConcreteClasses = true);
29 |
30 | ///
31 | /// Find classes of type
32 | ///
33 | /// Type
34 | /// Assemblies
35 | /// A value indicating whether to find only concrete classes
36 | /// Result
37 | IEnumerable FindClassesOfType(IEnumerable assemblies, bool onlyConcreteClasses = true);
38 |
39 | ///
40 | /// Find classes of type
41 | ///
42 | /// Assign type from
43 | /// Assemblies
44 | /// A value indicating whether to find only concrete classes
45 | /// Result
46 | IEnumerable FindClassesOfType(Type assignTypeFrom, IEnumerable assemblies, bool onlyConcreteClasses = true);
47 |
48 | ///
49 | /// Gets the assemblies related to the current implementation.
50 | ///
51 | /// A list of assemblies
52 | IList GetAssemblies();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/AA.FrameWork/Engine/Singleton.cs:
--------------------------------------------------------------------------------
1 | namespace AA.FrameWork.Engine
2 | {
3 | ///
4 | /// A statically compiled "singleton" used to store objects throughout the
5 | /// lifetime of the app domain. Not so much singleton in the pattern's
6 | /// sense of the word as a standardized way to store single instances.
7 | ///
8 | /// The type of object to store.
9 | /// Access to the instance is not synchronized.
10 | public class Singleton : BaseSingleton
11 | {
12 | private static T instance;
13 |
14 | ///
15 | /// The singleton instance for the specified type T. Only one instance (at the time) of this object for each type of T.
16 | ///
17 | public static T Instance
18 | {
19 | get => instance;
20 | set
21 | {
22 | instance = value;
23 | AllSingletons[typeof(T)] = value;
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/AA.FrameWork/Engine/SingletonDictionary.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace AA.FrameWork.Engine
4 | {
5 | ///
6 | /// Provides a singleton dictionary for a certain key and vlaue type.
7 | ///
8 | /// The type of key.
9 | /// The type of value.
10 | public class SingletonDictionary : Singleton>
11 | {
12 | static SingletonDictionary()
13 | {
14 | Singleton>.Instance = new Dictionary();
15 | }
16 |
17 | ///
18 | /// The singleton instance for the specified type T. Only one instance (at the time) of this dictionary for each type of T.
19 | ///
20 | public new static IDictionary Instance => Singleton>.Instance;
21 | }
22 | }
--------------------------------------------------------------------------------
/AA.FrameWork/Engine/SingletonList.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace AA.FrameWork.Engine
4 | {
5 | ///
6 | /// Provides a singleton list for a certain type.
7 | ///
8 | /// The type of list to store.
9 | public class SingletonList : Singleton>
10 | {
11 | static SingletonList()
12 | {
13 | Singleton>.Instance = new List();
14 | }
15 |
16 | ///
17 | /// The singleton instance for the specified type T. Only one instance (at the time) of this list for each type of T.
18 | ///
19 | public new static IList Instance => Singleton>.Instance;
20 | }
21 | }
--------------------------------------------------------------------------------
/AA.FrameWork/Extensions/DateTimeExtension.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace AA.FrameWork.Extensions
4 | {
5 | public static class DateTimeExtension
6 | {
7 | public static DateTime DBNull = "1900-01-01 00:00:00".TryDateTime();
8 |
9 | ///
10 | /// 判断DateTime在数据库中是否存储为象征意义的null
11 | ///
12 | ///
13 | ///
14 | public static bool IsDBNull(this DateTime dateTime)
15 | {
16 | return dateTime == DBNull;
17 | }
18 |
19 | ///
20 | /// 判断DateTime在数据库中是否存储为象征意义的null
21 | ///
22 | ///
23 | ///
24 | public static bool IsDBNull(this DateTime? dateTime)
25 | {
26 | return dateTime == null || dateTime == DBNull;
27 | }
28 |
29 | ///
30 | /// 格式化为字符串
31 | ///
32 | ///
33 | ///
34 | public static string Format(this DateTime dateTime)
35 | {
36 | return dateTime.ToString("yyyy-MM-dd HH:mm:ss");
37 | }
38 |
39 |
40 | public static string ToFriendTime(this DateTime dt)
41 | {
42 | TimeSpan span = DateTime.Now - dt;
43 |
44 | if (span.TotalSeconds < 60)
45 | {
46 | return Math.Round((span.TotalSeconds < 5 ? 5 : span.TotalSeconds), 0) + "秒钟前";
47 | }
48 | if (span.TotalMinutes < 60)
49 | {
50 | return Math.Round(span.TotalMinutes, 0) + "分钟前";
51 | }
52 | if (span.TotalHours < 5)
53 | {
54 | if (span.Minutes > 0)
55 | {
56 | return span.Hours + "小时" + span.Minutes + "分钟前";
57 | }
58 | else
59 | {
60 | return span.Hours + "小时前";
61 | }
62 | }
63 | if (span.TotalDays < 1 && DateTime.Now.Day == dt.Day)
64 | {
65 | return "今天 " + dt.ToString("HH:mm") + "";
66 | }
67 | if (span.TotalDays < 1 && DateTime.Now.Day > dt.Day)
68 | {
69 | return "昨天 " + dt.ToString("HH:mm") + "";
70 | }
71 | if (span.TotalDays < 2 && span.TotalDays >= 1 && (DateTime.Now.Day - dt.Day) == 1)
72 | {
73 | return "昨天 " + dt.ToString("HH:mm") + "";
74 | }
75 | if (span.TotalDays < 3 && (DateTime.Now.Day - dt.Day) == 2)
76 | {
77 | return "前天 " + dt.ToString("HH:mm") + "";
78 | }
79 | //if (span.TotalDays <= 30 && dt.Year == DateTime.Now.Year)
80 | //{
81 | // return dt.ToString("MM月dd日");
82 | //}
83 |
84 | return dt.ToString("yyyy-MM-dd HH:mm") + "";
85 | }
86 | }
87 | }
--------------------------------------------------------------------------------
/AA.FrameWork/Extensions/GuidExtension.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace AA.FrameWork.Extensions
8 | {
9 | public static class GuidExtension
10 | {
11 | #region verify Guid is empty or not
12 |
13 | ///
14 | /// verify Guid is empty or not
15 | ///
16 | /// Guid value
17 | /// is empty or not
18 | public static bool IsEmpty(this Guid value)
19 | {
20 | return value == Guid.Empty;
21 | }
22 |
23 | #endregion
24 |
25 | #region convert Guid to Int64
26 |
27 | ///
28 | /// convert Guid to Int64
29 | ///
30 | /// Guid value
31 | /// Int64 value
32 | public static long ToInt64(this Guid value)
33 | {
34 | byte[] bytes = value.ToByteArray();
35 | return BitConverter.ToInt64(bytes, 0);
36 | }
37 |
38 | #endregion
39 |
40 | #region convert Guid to Int32
41 |
42 | ///
43 | /// convert Guid to Int32
44 | ///
45 | /// Guid value
46 | /// Int32 value
47 | public static int ToInt32(this Guid value)
48 | {
49 | byte[] bytes = value.ToByteArray();
50 | return BitConverter.ToInt32(bytes, 0);
51 | }
52 |
53 | #endregion
54 |
55 | #region convert guid to uniquecode(formatting to upper)
56 |
57 | ///
58 | /// convert guid to uniquecode(Upper)
59 | ///
60 | /// Guid value
61 | /// uniquecode value
62 | public static string ToUniqueCode(this Guid value)
63 | {
64 | long i = 1;
65 | byte[] bytes = value.ToByteArray();
66 | foreach (byte b in bytes)
67 | {
68 | i *= ((int)b + 1);
69 | }
70 | string code = string.Format("{0:x}", i - DateTime.Now.Ticks);
71 | return code;
72 | }
73 |
74 | #endregion
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/AA.FrameWork/Extensions/StringExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Text;
5 |
6 | namespace AA.FrameWork.Extensions
7 | {
8 | ///
9 | /// Extension methods for .
10 | ///
11 | public static class StringExtensions
12 | {
13 | ///
14 | /// Allows null-safe trimming of string.
15 | ///
16 | ///
17 | ///
18 | public static string NullSafeTrim(this string s)
19 | {
20 | return s?.Trim();
21 | }
22 |
23 | ///
24 | /// Trims string and if resulting string is empty, null is returned.
25 | ///
26 | ///
27 | ///
28 | public static string TrimEmptyToNull(this string s)
29 | {
30 | if (s == null)
31 | {
32 | return null;
33 | }
34 |
35 | s = s.Trim();
36 |
37 | if (s.Length == 0)
38 | {
39 | return null;
40 | }
41 |
42 | return s;
43 | }
44 |
45 | public static bool IsNullOrWhiteSpace(this string s)
46 | {
47 | return s == null || s.Trim().Length == 0;
48 | }
49 |
50 | public static string FormatInvariant(this string s, params object[] args)
51 | {
52 | return string.Format(CultureInfo.InvariantCulture, s, args);
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/AA.FrameWork/Logging/ILogger.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace AA.FrameWork.Logging
6 | {
7 | public interface ILogger
8 | {
9 | ILog Get(string name);
10 | void Shutdown();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/AA.FrameWork/Logging/Ilog.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace AA.FrameWork.Logging
6 | {
7 | public interface ILog
8 | {
9 | bool IsDebugEnabled { get; }
10 | bool IsInfoEnabled { get; }
11 | bool IsWarnEnabled { get; }
12 | bool IsErrorEnabled { get; }
13 | bool IsFatalEnabled { get; }
14 |
15 | //void Log(LogLevel level, object obj);
16 | //void Log(LogLevel level, object obj, Exception exception);
17 | //void Log(LogLevel level, LogOutputProvider messageProvider);
18 | //void LogFormat(LogLevel level, IFormatProvider formatProvider, string format, params object[] args);
19 | //void LogFormat(LogLevel level, string format, params object[] args);
20 |
21 | void Debug(object obj);
22 | void Debug(object obj, Exception exception);
23 |
24 | void DebugFormat(IFormatProvider formatProvider, string format, params object[] args);
25 | void DebugFormat(string format, params object[] args);
26 |
27 | void Info(object obj);
28 | void Info(object obj, Exception exception);
29 |
30 | void InfoFormat(IFormatProvider formatProvider, string format, params object[] args);
31 | void InfoFormat(string format, params object[] args);
32 |
33 | void Warn(object obj);
34 | void Warn(object obj, Exception exception);
35 |
36 | void WarnFormat(IFormatProvider formatProvider, string format, params object[] args);
37 | void WarnFormat(string format, params object[] args);
38 |
39 | void Error(object obj);
40 | void Error(object obj, Exception exception);
41 |
42 | void ErrorFormat(IFormatProvider formatProvider, string format, params object[] args);
43 | void ErrorFormat(string format, params object[] args);
44 |
45 | void Fatal(object obj);
46 | void Fatal(object obj, Exception exception);
47 | void FatalFormat(IFormatProvider formatProvider, string format, params object[] args);
48 | void FatalFormat(string format, params object[] args);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/AA.FrameWork/Logging/Logger.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace AA.FrameWork.Logging
6 | {
7 | public static class Logger
8 | {
9 | static ILogger _logger;
10 | public static ILogger Current => _logger;
11 |
12 | public static ILog Get(Type type)
13 | {
14 | return Get(type.FullName);
15 | }
16 |
17 | public static ILog Get(string name)
18 | {
19 | return Current.Get(name);
20 | }
21 |
22 | public static void UseLogger(ILogger logger)
23 | {
24 | _logger = logger;
25 | }
26 |
27 | public static void Shutdown()
28 | {
29 | _logger?.Shutdown();
30 | }
31 |
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/AA.FrameWork/ObjectMapping/IObjectMapper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace AA.FrameWork.ObjectMapping
8 | {
9 | ///
10 | /// Defines a simple interface to map objects.
11 | ///
12 | public interface IObjectMapper
13 | {
14 | ///
15 | /// Converts an object to another. Creates a new object of .
16 | ///
17 | /// Type of the destination object
18 | /// Source object
19 | TDestination Map(object source);
20 |
21 | ///
22 | /// Execute a mapping from the source object to the existing destination object
23 | ///
24 | /// Source type
25 | /// Destination type
26 | /// Source object
27 | /// Returns the same object after mapping operation
28 | TDestination Map(TSource source);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/AA.FrameWork/ObjectMapping/ObjectMapManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace AA.FrameWork.ObjectMapping
8 | {
9 | public static class ObjectMapManager
10 | {
11 | ///
12 | /// Object Mapper
13 | ///
14 | public static IObjectMapper ObjectMapper { get; set; }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/AA.FrameWork/Serialize/ISerialize.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace AA.FrameWork.Serialize
6 | {
7 | public interface ISerialize
8 | {
9 |
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/AA.FrameWork/Util/CodeUtil.cs:
--------------------------------------------------------------------------------
1 | using AA.FrameWork.Extensions;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace AA.FrameWork.Util
9 | {
10 | public static class CodeUtil
11 | {
12 | #region generate a guid code
13 |
14 | ///
15 | /// generate a guid code
16 | ///
17 | /// guid code
18 | public static Guid GetGuidCode()
19 | {
20 | return Guid.NewGuid();
21 | }
22 |
23 | #endregion
24 |
25 | #region generate a int64 number by guid
26 |
27 | ///
28 | /// generate a int64 number by guid
29 | ///
30 | ///
31 | public static long GetInt64UniqueCode()
32 | {
33 | Guid value = Guid.NewGuid();
34 | return value.ToInt64();
35 | }
36 |
37 | ///
38 | /// generate a int32 number by guid
39 | ///
40 | ///
41 | public static int GetInt32UniqueCode()
42 | {
43 | Guid value = Guid.NewGuid();
44 | int numOne = value.ToInt32();
45 | Guid valueTwo = Guid.NewGuid();
46 | int numTwo = valueTwo.ToInt32();
47 | return Math.Abs(numTwo + numOne);
48 | }
49 |
50 | #endregion
51 |
52 | #region generate a unique code by guid
53 |
54 | ///
55 | /// generate a unique code by guid
56 | ///
57 | ///
58 | public static string GetUniqueCode()
59 | {
60 | Guid value = Guid.NewGuid();
61 | return value.ToUniqueCode();
62 | }
63 |
64 | #endregion
65 |
66 | #region generate a specified length code by uniquecode
67 |
68 | ///
69 | /// generate a specified length code by uniquecode,too ensure uniqueness,recommend to set length at least 16
70 | ///
71 | /// code length
72 | /// prefix
73 | /// unique code
74 | public static string GetUniqueCode(int length, string prefix = "")
75 | {
76 | string uniqueCode = prefix + GetUniqueCode().ToUpper();
77 | if (uniqueCode.Length == length)
78 | {
79 | return uniqueCode;
80 | }
81 | if (uniqueCode.Length > length)
82 | {
83 | uniqueCode = uniqueCode.Substring(0, length);
84 | }
85 | else
86 | {
87 | string codeString = "1a2b3c4d5e6f7g8h9i0j9k8l7m6n5o4p3q2r1s0t1u2v3w4x5y6z".ToUpper();
88 | int randomNum = length - uniqueCode.Length;
89 | int randomLength = codeString.Length;
90 | Random random = new Random();
91 | for (var r = 0; r < randomNum; r++)
92 | {
93 | int csnum = random.Next(randomLength);
94 | uniqueCode += codeString[csnum];
95 | }
96 | }
97 | return uniqueCode;
98 | }
99 |
100 | #endregion
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/AA.FrameWork/Util/ForCallContext.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Concurrent;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading;
7 | #if NETFX
8 | using System.Runtime.Remoting.Messaging;
9 | #endif
10 | namespace AA.FrameWork.Util
11 | {
12 | public static class ForCallContext
13 | {
14 | #if NETFX
15 | #else
16 | static ConcurrentDictionary> state = new ConcurrentDictionary>();
17 | #endif
18 |
19 | public static void SetData(string name, object data) =>
20 | #if NETFX
21 | CallContext.LogicalSetData(name, data);
22 | #else
23 | state.GetOrAdd(name, _ => new AsyncLocal