- 增加 FreeSql.Provider.Sqlite 对 Xamarin 环境下的适配;

This commit is contained in:
28810 2019-11-07 12:22:01 +08:00
parent 5521d6d100
commit 8cc5a682da
7 changed files with 98 additions and 86 deletions

View File

@ -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>
添加 添加

View 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
}
}

View File

@ -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>

View File

@ -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;
}
}
}

View File

@ -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)

View File

@ -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;
} }

View File

@ -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;