mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 01:05:27 +08:00 
			
		
		
		
	- 增加 FreeSql.Provider.Sqlite 对 Xamarin 环境下的适配;
This commit is contained in:
		@@ -99,6 +99,13 @@
 | 
				
			|||||||
            清空状态数据
 | 
					            清空状态数据
 | 
				
			||||||
            </summary>
 | 
					            </summary>
 | 
				
			||||||
        </member>
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.DbSet`1.RemoveAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            根据 lambda 条件删除数据
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <param name="predicate"></param>
 | 
				
			||||||
 | 
					            <returns></returns>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
        <member name="M:FreeSql.DbSet`1.Add(`0)">
 | 
					        <member name="M:FreeSql.DbSet`1.Add(`0)">
 | 
				
			||||||
            <summary>
 | 
					            <summary>
 | 
				
			||||||
            添加
 | 
					            添加
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										61
									
								
								Providers/FreeSql.Provider.Sqlite/AdonetPortable.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								Providers/FreeSql.Provider.Sqlite/AdonetPortable.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Data.Common;
 | 
				
			||||||
 | 
					using System.Reflection;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace FreeSql.Sqlite
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    internal class AdonetPortable
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if ns20
 | 
				
			||||||
 | 
					        static bool _IsMicrosoft_Data_Sqlite;
 | 
				
			||||||
 | 
					        static object _IsMicrosoft_Data_SqliteLock = new object();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        static T PortableAction<T>(Func<T> systemCreate, Func<T> microsoftCreate)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (_IsMicrosoft_Data_Sqlite == false)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                try
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return systemCreate();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                catch
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    lock (_IsMicrosoft_Data_SqliteLock)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        _IsMicrosoft_Data_Sqlite = true;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return microsoftCreate();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static DbConnection GetSqliteConnection(string connectionString) => PortableAction<DbConnection>(
 | 
				
			||||||
 | 
					            () => new System.Data.SQLite.SQLiteConnection(connectionString), 
 | 
				
			||||||
 | 
					            () => new Microsoft.Data.Sqlite.SqliteConnection(connectionString));
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					        public static DbCommand GetSqliteCommand() => PortableAction<DbCommand>(
 | 
				
			||||||
 | 
					            () => new System.Data.SQLite.SQLiteCommand(),
 | 
				
			||||||
 | 
					            () => new Microsoft.Data.Sqlite.SqliteCommand());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static DbParameter GetSqliteParameter() => PortableAction<DbParameter>(
 | 
				
			||||||
 | 
					            () => new System.Data.SQLite.SQLiteParameter(),
 | 
				
			||||||
 | 
					            () => new Microsoft.Data.Sqlite.SqliteParameter());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static bool IsSqliteException(Exception exception) => PortableAction<bool>(
 | 
				
			||||||
 | 
					            () => exception is System.Data.SQLite.SQLiteException,
 | 
				
			||||||
 | 
					            () => exception is Microsoft.Data.Sqlite.SqliteException);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static DbConnection GetSqliteConnection(string connectionString) => new System.Data.SQLite.SQLiteConnection(connectionString);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					        public static DbCommand GetSqliteCommand() => new System.Data.SQLite.SQLiteCommand();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static DbParameter GetSqliteParameter() => new System.Data.SQLite.SQLiteParameter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static bool IsSqliteException(Exception exception) => exception is System.Data.SQLite.SQLiteException;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	<PropertyGroup>
 | 
						<PropertyGroup>
 | 
				
			||||||
		<TargetFrameworks>netstandard2.0;net45;net40</TargetFrameworks>
 | 
							<TargetFrameworks>netstandard2.0;net45;net40</TargetFrameworks>
 | 
				
			||||||
		<Version>0.11.9</Version>
 | 
							<Version>0.11.9.2</Version>
 | 
				
			||||||
		<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
 | 
							<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
 | 
				
			||||||
		<Authors>YeXiangQin</Authors>
 | 
							<Authors>YeXiangQin</Authors>
 | 
				
			||||||
		<Description>FreeSql 数据库实现,基于 Sqlite 3.0</Description>
 | 
							<Description>FreeSql 数据库实现,基于 Sqlite 3.0</Description>
 | 
				
			||||||
@@ -25,11 +25,17 @@
 | 
				
			|||||||
	<ItemGroup>
 | 
						<ItemGroup>
 | 
				
			||||||
	  <PackageReference Include="System.Data.SQLite.Core" Version="1.0.112" />
 | 
						  <PackageReference Include="System.Data.SQLite.Core" Version="1.0.112" />
 | 
				
			||||||
	</ItemGroup>
 | 
						</ItemGroup>
 | 
				
			||||||
 | 
					  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
 | 
				
			||||||
 | 
					    <PackageReference Include="Microsoft.Data.Sqlite" Version="3.0.0" />
 | 
				
			||||||
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<ItemGroup>
 | 
						<ItemGroup>
 | 
				
			||||||
	  <ProjectReference Include="..\..\FreeSql\FreeSql.csproj" />
 | 
						  <ProjectReference Include="..\..\FreeSql\FreeSql.csproj" />
 | 
				
			||||||
	</ItemGroup>
 | 
						</ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
 | 
				
			||||||
 | 
					    <DefineConstants>ns20;netstandard20</DefineConstants>
 | 
				
			||||||
 | 
					  </PropertyGroup>
 | 
				
			||||||
  <PropertyGroup Condition="'$(TargetFramework)' == 'net40'">
 | 
					  <PropertyGroup Condition="'$(TargetFramework)' == 'net40'">
 | 
				
			||||||
    <DefineConstants>net40</DefineConstants>
 | 
					    <DefineConstants>net40</DefineConstants>
 | 
				
			||||||
  </PropertyGroup>
 | 
					  </PropertyGroup>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,72 +0,0 @@
 | 
				
			|||||||
using System;
 | 
					 | 
				
			||||||
using System.Collections.Generic;
 | 
					 | 
				
			||||||
using System.Data.Common;
 | 
					 | 
				
			||||||
using System.Reflection;
 | 
					 | 
				
			||||||
using System.Text;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace FreeSql.Sqlite
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    internal class MonoAdapter
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        static bool? _isMono;
 | 
					 | 
				
			||||||
        static object _isMonoLock = new object();
 | 
					 | 
				
			||||||
        static Assembly _monoAssemly;
 | 
					 | 
				
			||||||
        static Type _monoSqliteConnectionType;
 | 
					 | 
				
			||||||
        static Type _monoSqliteCommandType;
 | 
					 | 
				
			||||||
        static Type _monoSqliteParameterType;
 | 
					 | 
				
			||||||
        static Type _monoSqliteExceptionType;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        static bool IsMono
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            get
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (_isMono != null) return _isMono == true;
 | 
					 | 
				
			||||||
                lock (_isMonoLock)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    Assembly ass = null;
 | 
					 | 
				
			||||||
                    try
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        ass = Assembly.Load("Mono.Data.Sqlite");
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    catch { }
 | 
					 | 
				
			||||||
                    _isMono = ass != null;
 | 
					 | 
				
			||||||
                    if (_isMono == false) return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    _monoAssemly = ass;
 | 
					 | 
				
			||||||
                    _monoSqliteConnectionType = _monoAssemly.GetType("Mono.Data.Sqlite.SqliteConnection");
 | 
					 | 
				
			||||||
                    _monoSqliteCommandType = _monoAssemly.GetType("Mono.Data.Sqlite.SqliteCommand");
 | 
					 | 
				
			||||||
                    _monoSqliteParameterType = _monoAssemly.GetType("Mono.Data.Sqlite.SqliteParameter");
 | 
					 | 
				
			||||||
                    _monoSqliteExceptionType = _monoAssemly.GetType("Mono.Data.Sqlite.SqliteException");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public static DbConnection GetSqliteConnection(string connectionString)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (IsMono == false) return new System.Data.SQLite.SQLiteConnection(connectionString);
 | 
					 | 
				
			||||||
            return Activator.CreateInstance(_monoSqliteConnectionType, new object[] { connectionString }) as DbConnection;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public static DbCommand GetSqliteCommand()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (IsMono == false) return new System.Data.SQLite.SQLiteCommand();
 | 
					 | 
				
			||||||
            return Activator.CreateInstance(_monoSqliteCommandType, new object[0]) as DbCommand;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public static DbParameter GetSqliteParameter()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (IsMono == false) return new System.Data.SQLite.SQLiteParameter();
 | 
					 | 
				
			||||||
            return Activator.CreateInstance(_monoSqliteParameterType, new object[0]) as DbParameter;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public static bool IsSqliteException(Exception exception)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (exception == null) return false;
 | 
					 | 
				
			||||||
            if (IsMono == false) return exception is System.Data.SQLite.SQLiteException;
 | 
					 | 
				
			||||||
            return exception.GetType() == _monoSqliteExceptionType;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -55,7 +55,7 @@ namespace FreeSql.Sqlite
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        protected override DbCommand CreateCommand()
 | 
					        protected override DbCommand CreateCommand()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return MonoAdapter.GetSqliteCommand();
 | 
					            return AdonetPortable.GetSqliteCommand();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override void ReturnConnection(ObjectPool<DbConnection> pool, Object<DbConnection> conn, Exception ex)
 | 
					        protected override void ReturnConnection(ObjectPool<DbConnection> pool, Object<DbConnection> conn, Exception ex)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,7 +34,7 @@ namespace FreeSql.Sqlite
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        public void Return(Object<DbConnection> obj, Exception exception, bool isRecreate = false)
 | 
					        public void Return(Object<DbConnection> obj, Exception exception, bool isRecreate = false)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (exception != null && MonoAdapter.IsSqliteException(exception))
 | 
					            if (exception != null && AdonetPortable.IsSqliteException(exception))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                try { if (obj.Value.Ping() == false) obj.Value.OpenAndAttach(policy.Attaches); } catch { base.SetUnavailable(exception); }
 | 
					                try { if (obj.Value.Ping() == false) obj.Value.OpenAndAttach(policy.Attaches); } catch { base.SetUnavailable(exception); }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -57,7 +57,6 @@ namespace FreeSql.Sqlite
 | 
				
			|||||||
        public int CheckAvailableInterval { get; set; } = 5;
 | 
					        public int CheckAvailableInterval { get; set; } = 5;
 | 
				
			||||||
        public string[] Attaches = new string[0];
 | 
					        public string[] Attaches = new string[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        static ConcurrentDictionary<string, int> dicConnStrIncr = new ConcurrentDictionary<string, int>(StringComparer.CurrentCultureIgnoreCase);
 | 
					 | 
				
			||||||
        private string _connectionString;
 | 
					        private string _connectionString;
 | 
				
			||||||
        public string ConnectionString
 | 
					        public string ConnectionString
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -68,12 +67,11 @@ namespace FreeSql.Sqlite
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)";
 | 
					                var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)";
 | 
				
			||||||
                Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
 | 
					                Match m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
 | 
				
			||||||
                if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
 | 
					                if (m.Success)
 | 
				
			||||||
                var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1);
 | 
					                {
 | 
				
			||||||
                PoolSize = poolsize + connStrIncr;
 | 
					                    PoolSize = int.Parse(m.Groups[1].Value);
 | 
				
			||||||
                _connectionString = m.Success ?
 | 
					                    _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase);
 | 
				
			||||||
                    Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) :
 | 
					                }
 | 
				
			||||||
                    $"{_connectionString};Max pool size={PoolSize}";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                pattern = @"Connection\s*LifeTime\s*=\s*(\d+)";
 | 
					                pattern = @"Connection\s*LifeTime\s*=\s*(\d+)";
 | 
				
			||||||
                m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
 | 
					                m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
 | 
				
			||||||
@@ -92,14 +90,26 @@ namespace FreeSql.Sqlite
 | 
				
			|||||||
                    _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase);
 | 
					                    _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var att = Regex.Split(_connectionString, @"Attachs\s*=\s*", RegexOptions.IgnoreCase);
 | 
					                var att = Regex.Split(_connectionString, @"Pooling\s*=\s*", RegexOptions.IgnoreCase);
 | 
				
			||||||
 | 
					                if (att.Length == 2)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    var idx = att[1].IndexOf(';');
 | 
				
			||||||
 | 
					                    _connectionString = string.Concat(att[0], idx == -1 ? "" : att[1].Substring(idx));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                att = Regex.Split(_connectionString, @"Attachs\s*=\s*", RegexOptions.IgnoreCase);
 | 
				
			||||||
                if (att.Length == 2)
 | 
					                if (att.Length == 2)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var idx = att[1].IndexOf(';');
 | 
					                    var idx = att[1].IndexOf(';');
 | 
				
			||||||
                    Attaches = (idx == -1 ? att[1] : att[1].Substring(0, idx)).Split(',');
 | 
					                    Attaches = (idx == -1 ? att[1] : att[1].Substring(0, idx)).Split(',');
 | 
				
			||||||
 | 
					                    _connectionString = string.Concat(att[0], idx == -1 ? "" : att[1].Substring(idx));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if ns20
 | 
				
			||||||
 | 
					                minPoolSize = 1;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
                FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize);
 | 
					                FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -111,7 +121,7 @@ namespace FreeSql.Sqlite
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        public DbConnection OnCreate()
 | 
					        public DbConnection OnCreate()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var conn = MonoAdapter.GetSqliteConnection(_connectionString);
 | 
					            var conn = AdonetPortable.GetSqliteConnection(_connectionString);
 | 
				
			||||||
            return conn;
 | 
					            return conn;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,7 +33,7 @@ namespace FreeSql.Sqlite
 | 
				
			|||||||
                    dbtype = DbType.Int64;
 | 
					                    dbtype = DbType.Int64;
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            var ret = MonoAdapter.GetSqliteParameter();
 | 
					            var ret = AdonetPortable.GetSqliteParameter();
 | 
				
			||||||
            ret.ParameterName = QuoteParamterName(parameterName);
 | 
					            ret.ParameterName = QuoteParamterName(parameterName);
 | 
				
			||||||
            ret.DbType = dbtype;
 | 
					            ret.DbType = dbtype;
 | 
				
			||||||
            ret.Value = value;
 | 
					            ret.Value = value;
 | 
				
			||||||
@@ -58,7 +58,7 @@ namespace FreeSql.Sqlite
 | 
				
			|||||||
                        dbtype = DbType.Int64;
 | 
					                        dbtype = DbType.Int64;
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                var ret = MonoAdapter.GetSqliteParameter();
 | 
					                var ret = AdonetPortable.GetSqliteParameter();
 | 
				
			||||||
                ret.ParameterName = $"@{name}";
 | 
					                ret.ParameterName = $"@{name}";
 | 
				
			||||||
                ret.DbType = dbtype;
 | 
					                ret.DbType = dbtype;
 | 
				
			||||||
                ret.Value = value;
 | 
					                ret.Value = value;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user