mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	- 增加 FreeSql.Provider.Sqlite 对 Xamarin 环境下的适配;
This commit is contained in:
		@@ -99,6 +99,13 @@
 | 
			
		||||
            清空状态数据
 | 
			
		||||
            </summary>
 | 
			
		||||
        </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)">
 | 
			
		||||
            <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>
 | 
			
		||||
		<TargetFrameworks>netstandard2.0;net45;net40</TargetFrameworks>
 | 
			
		||||
		<Version>0.11.9</Version>
 | 
			
		||||
		<Version>0.11.9.2</Version>
 | 
			
		||||
		<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
 | 
			
		||||
		<Authors>YeXiangQin</Authors>
 | 
			
		||||
		<Description>FreeSql 数据库实现,基于 Sqlite 3.0</Description>
 | 
			
		||||
@@ -25,11 +25,17 @@
 | 
			
		||||
	<ItemGroup>
 | 
			
		||||
	  <PackageReference Include="System.Data.SQLite.Core" Version="1.0.112" />
 | 
			
		||||
	</ItemGroup>
 | 
			
		||||
  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
 | 
			
		||||
    <PackageReference Include="Microsoft.Data.Sqlite" Version="3.0.0" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
	<ItemGroup>
 | 
			
		||||
	  <ProjectReference Include="..\..\FreeSql\FreeSql.csproj" />
 | 
			
		||||
	</ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
 | 
			
		||||
    <DefineConstants>ns20;netstandard20</DefineConstants>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(TargetFramework)' == 'net40'">
 | 
			
		||||
    <DefineConstants>net40</DefineConstants>
 | 
			
		||||
  </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()
 | 
			
		||||
        {
 | 
			
		||||
            return MonoAdapter.GetSqliteCommand();
 | 
			
		||||
            return AdonetPortable.GetSqliteCommand();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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)
 | 
			
		||||
        {
 | 
			
		||||
            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); }
 | 
			
		||||
            }
 | 
			
		||||
@@ -57,7 +57,6 @@ namespace FreeSql.Sqlite
 | 
			
		||||
        public int CheckAvailableInterval { get; set; } = 5;
 | 
			
		||||
        public string[] Attaches = new string[0];
 | 
			
		||||
 | 
			
		||||
        static ConcurrentDictionary<string, int> dicConnStrIncr = new ConcurrentDictionary<string, int>(StringComparer.CurrentCultureIgnoreCase);
 | 
			
		||||
        private string _connectionString;
 | 
			
		||||
        public string ConnectionString
 | 
			
		||||
        {
 | 
			
		||||
@@ -68,12 +67,11 @@ namespace FreeSql.Sqlite
 | 
			
		||||
 | 
			
		||||
                var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)";
 | 
			
		||||
                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;
 | 
			
		||||
                var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1);
 | 
			
		||||
                PoolSize = poolsize + connStrIncr;
 | 
			
		||||
                _connectionString = m.Success ?
 | 
			
		||||
                    Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) :
 | 
			
		||||
                    $"{_connectionString};Max pool size={PoolSize}";
 | 
			
		||||
                if (m.Success)
 | 
			
		||||
                {
 | 
			
		||||
                    PoolSize = int.Parse(m.Groups[1].Value);
 | 
			
		||||
                    _connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                pattern = @"Connection\s*LifeTime\s*=\s*(\d+)";
 | 
			
		||||
                m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
 | 
			
		||||
@@ -92,14 +90,26 @@ namespace FreeSql.Sqlite
 | 
			
		||||
                    _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)
 | 
			
		||||
                {
 | 
			
		||||
                    var idx = att[1].IndexOf(';');
 | 
			
		||||
                    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);
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -111,7 +121,7 @@ namespace FreeSql.Sqlite
 | 
			
		||||
 | 
			
		||||
        public DbConnection OnCreate()
 | 
			
		||||
        {
 | 
			
		||||
            var conn = MonoAdapter.GetSqliteConnection(_connectionString);
 | 
			
		||||
            var conn = AdonetPortable.GetSqliteConnection(_connectionString);
 | 
			
		||||
            return conn;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,7 @@ namespace FreeSql.Sqlite
 | 
			
		||||
                    dbtype = DbType.Int64;
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            var ret = MonoAdapter.GetSqliteParameter();
 | 
			
		||||
            var ret = AdonetPortable.GetSqliteParameter();
 | 
			
		||||
            ret.ParameterName = QuoteParamterName(parameterName);
 | 
			
		||||
            ret.DbType = dbtype;
 | 
			
		||||
            ret.Value = value;
 | 
			
		||||
@@ -58,7 +58,7 @@ namespace FreeSql.Sqlite
 | 
			
		||||
                        dbtype = DbType.Int64;
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
                var ret = MonoAdapter.GetSqliteParameter();
 | 
			
		||||
                var ret = AdonetPortable.GetSqliteParameter();
 | 
			
		||||
                ret.ParameterName = $"@{name}";
 | 
			
		||||
                ret.DbType = dbtype;
 | 
			
		||||
                ret.Value = value;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user