mirror of
https://gitee.com/dotnetchina/SqlSugar.git
synced 2025-04-05 17:37:58 +08:00
修复DB2 V11.5版本变量参数化异常问题
This commit is contained in:
parent
db3dd58302
commit
686c3d249f
@ -26,127 +26,228 @@ namespace DB2CoreTest.CURD
|
||||
|
||||
public static void Insertable()
|
||||
{
|
||||
// 获取新的数据库实例
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
//插入用户
|
||||
var userId = db.Insertable(new UserInfo()
|
||||
try
|
||||
{
|
||||
Context = "Context",
|
||||
Email = "dfafa@qq.com",
|
||||
Price = Convert.ToDecimal(1.1),
|
||||
UserName = "admin",
|
||||
RegistrationDate = DateTime.Now,
|
||||
// 获取新的数据库实例
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
}).ExecuteReturnIdentity();
|
||||
//插入用户
|
||||
var userId = db.Insertable(new UserInfo()
|
||||
{
|
||||
Context = "Context",
|
||||
Email = "dfafa@qq.com",
|
||||
Price = Convert.ToDecimal(1.1),
|
||||
UserName = "admin",
|
||||
RegistrationDate = DateTime.Now,
|
||||
|
||||
//插入用户登录
|
||||
var loginId = db.Insertable(new UserLogins()
|
||||
}).ExecuteReturnIdentity();
|
||||
|
||||
//插入用户登录
|
||||
var loginId = db.Insertable(new UserLogins()
|
||||
{
|
||||
LoginTime = DateTime.Now,
|
||||
UserId = userId,
|
||||
|
||||
}).ExecuteReturnIdentity();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoginTime = DateTime.Now,
|
||||
UserId = userId,
|
||||
|
||||
}).ExecuteReturnIdentity();
|
||||
Console.WriteLine($"Insertable发生异常,异常信息:{GetFullErrorMessage(ex)}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void Queryable()
|
||||
{
|
||||
// 获取新的数据库实例
|
||||
var db = DbHelper.GetNewDb();
|
||||
try
|
||||
{
|
||||
// 获取新的数据库实例
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
//查询用户
|
||||
var userInfo = db.Queryable<UserInfo>().ToList();
|
||||
//查询用户
|
||||
var userInfo = db.Queryable<UserInfo>().ToList();
|
||||
|
||||
//查询用户登录
|
||||
var userLogin = db.Queryable<UserLogins>().ToList();
|
||||
//查询用户登录
|
||||
var userLogin = db.Queryable<UserLogins>().ToList();
|
||||
|
||||
var user = userInfo.FirstOrDefault();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Queryable发生异常,异常信息:{GetFullErrorMessage(ex)}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void QueryableSelect()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 获取新的数据库实例
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
//查询用户
|
||||
var userInfo = db.Queryable<UserInfo>().First();
|
||||
|
||||
//常量赋值
|
||||
var alias = "zhangsan";
|
||||
var isActived = false;
|
||||
var userInfoConst = db.Queryable<UserInfo>().Select(p => new Student { Name = p.UserName, Alias = alias, IsActived = isActived }).ToList();
|
||||
//对象赋值
|
||||
var userInfoObject = db.Queryable<UserInfo>().Select(p => new Student { Name = p.UserName, Alias = userInfo.UserName, IsActived = userInfo.IsActived }).ToList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"QueryableSelect发生异常,异常信息:{GetFullErrorMessage(ex)}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void JoinQuery()
|
||||
{
|
||||
// 获取新的数据库实例
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
var queryResult = db.Queryable<UserInfo, UserLogins>((ui, ul) => new JoinQueryInfos(JoinType.Inner, ui.UserId == ul.UserId)).Select((ui, ul) => new
|
||||
try
|
||||
{
|
||||
ui.UserName,
|
||||
ul.LoginTime,
|
||||
}).ToList();
|
||||
// 获取新的数据库实例
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
var queryResult = db.Queryable<UserInfo, UserLogins>((ui, ul) => new JoinQueryInfos(JoinType.Inner, ui.UserId == ul.UserId)).Select((ui, ul) => new
|
||||
{
|
||||
ui.UserName,
|
||||
ul.LoginTime,
|
||||
}).ToList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"JoinQuery发生异常,异常信息:{GetFullErrorMessage(ex)}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void PageQuery()
|
||||
{
|
||||
// 获取新的数据库实例
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
//查询用户
|
||||
var userList = db.Queryable<UserInfo>().ToPageList(2, 2);
|
||||
|
||||
var queryResult = db.Queryable<UserInfo, UserLogins>((ui, ul) => new JoinQueryInfos(JoinType.Inner, ui.UserId == ul.UserId)).Select((ui, ul) => new
|
||||
try
|
||||
{
|
||||
ui.UserName,
|
||||
ul.LoginTime,
|
||||
}).ToPageList(2, 2);
|
||||
// 获取新的数据库实例
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
//查询用户
|
||||
var userList = db.Queryable<UserInfo>().ToPageList(2, 2);
|
||||
|
||||
var queryResult = db.Queryable<UserInfo, UserLogins>((ui, ul) => new JoinQueryInfos(JoinType.Inner, ui.UserId == ul.UserId)).Select((ui, ul) => new
|
||||
{
|
||||
ui.UserName,
|
||||
ul.LoginTime,
|
||||
}).ToPageList(2, 2);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"PageQuery发生异常,异常信息:{GetFullErrorMessage(ex)}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void OrderBy()
|
||||
{
|
||||
// 获取新的数据库实例
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
//查询用户
|
||||
var userList = db.Queryable<UserInfo>().OrderBy(p => p.UserName).ToList();
|
||||
|
||||
var queryResult = db.Queryable<UserInfo, UserLogins>((ui, ul) => new JoinQueryInfos(JoinType.Inner, ui.UserId == ul.UserId)).Select((ui, ul) => new
|
||||
try
|
||||
{
|
||||
ui.UserName,
|
||||
ul.LoginTime,
|
||||
}).OrderBy(ui => ui.UserName).ToList();
|
||||
// 获取新的数据库实例
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
//查询用户
|
||||
var userList = db.Queryable<UserInfo>().OrderBy(p => p.UserName).ToList();
|
||||
|
||||
var queryResult = db.Queryable<UserInfo, UserLogins>((ui, ul) => new JoinQueryInfos(JoinType.Inner, ui.UserId == ul.UserId)).Select((ui, ul) => new
|
||||
{
|
||||
ui.UserName,
|
||||
ul.LoginTime,
|
||||
}).OrderBy(ui => ui.UserName).ToList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"OrderBy发生异常,异常信息:{GetFullErrorMessage(ex)}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void GroupBy()
|
||||
{
|
||||
// 获取新的数据库实例
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
//查询用户
|
||||
var userList = db.Queryable<UserInfo>().GroupBy(p => p.Email).Select(p => new { UserId = SqlFunc.AggregateMax(p.UserId), p.Email, }).OrderBy(p => p.UserId).ToList();
|
||||
|
||||
var queryResult = db.Queryable<UserInfo, UserLogins>((ui, ul) => new JoinQueryInfos(JoinType.Inner, ui.UserId == ul.UserId)).GroupBy((ui, ul) =>
|
||||
new
|
||||
try
|
||||
{
|
||||
ui.UserName,
|
||||
})
|
||||
.Select((ui, ul) => new
|
||||
// 获取新的数据库实例
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
//查询用户
|
||||
var userList = db.Queryable<UserInfo>().GroupBy(p => p.Email).Select(p => new { UserId = SqlFunc.AggregateMax(p.UserId), p.Email, }).OrderBy(p => p.UserId).ToList();
|
||||
|
||||
var queryResult = db.Queryable<UserInfo, UserLogins>((ui, ul) => new JoinQueryInfos(JoinType.Inner, ui.UserId == ul.UserId)).GroupBy((ui, ul) =>
|
||||
new
|
||||
{
|
||||
ui.UserName,
|
||||
})
|
||||
.Select((ui, ul) => new
|
||||
{
|
||||
UserId = SqlFunc.AggregateMax(ui.UserId),
|
||||
ui.UserName,
|
||||
LoginTime = SqlFunc.AggregateMax(ul.LoginTime),
|
||||
}).OrderBy(ui => ui.UserName).ToList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
UserId = SqlFunc.AggregateMax(ui.UserId),
|
||||
ui.UserName,
|
||||
LoginTime = SqlFunc.AggregateMax(ul.LoginTime),
|
||||
}).OrderBy(ui => ui.UserName).ToList();
|
||||
Console.WriteLine($"GroupBy发生异常,异常信息:{GetFullErrorMessage(ex)}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void Updateable()
|
||||
{
|
||||
// 获取新的数据库实例
|
||||
var db = DbHelper.GetNewDb();
|
||||
try
|
||||
{
|
||||
// 获取新的数据库实例
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
//更新用户
|
||||
var ret = db.Updateable<UserInfo>(p => p.UserName == "test").Where(p => p.UserName == "admin").ExecuteCommand();
|
||||
//更新用户
|
||||
var ret = db.Updateable<UserInfo>(p => p.UserName == "test").Where(p => p.UserName == "admin").ExecuteCommand();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Updateable发生异常,异常信息:{GetFullErrorMessage(ex)}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void Deleteable()
|
||||
{
|
||||
// 获取新的数据库实例
|
||||
var db = DbHelper.GetNewDb();
|
||||
try
|
||||
{
|
||||
// 获取新的数据库实例
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
//查询用户
|
||||
var userList = db.Queryable<UserInfo>().ToList();
|
||||
//删除用户
|
||||
var deleteUserRet = db.Deleteable(userList).ExecuteCommand();
|
||||
//查询用户
|
||||
var userList = db.Queryable<UserInfo>().ToList();
|
||||
//删除用户
|
||||
var deleteUserRet = db.Deleteable(userList).ExecuteCommand();
|
||||
|
||||
//查询用户登录
|
||||
var userLoginList = db.Queryable<UserInfo>().ToList();
|
||||
//删除用户登录
|
||||
var deleteUserLoginRet = db.Deleteable(userLoginList).ExecuteCommand();
|
||||
//查询用户登录
|
||||
var userLoginList = db.Queryable<UserInfo>().ToList();
|
||||
//删除用户登录
|
||||
var deleteUserLoginRet = db.Deleteable(userLoginList).ExecuteCommand();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Deleteable发生异常,异常信息:{GetFullErrorMessage(ex)}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取完整的异常信息,包括堆栈信息
|
||||
/// </summary>
|
||||
/// <param name="ex">异常对象</param>
|
||||
/// <returns>返回完整异常信息</returns>
|
||||
private static string GetFullErrorMessage(Exception ex)
|
||||
{
|
||||
var message = new StringBuilder();
|
||||
message.AppendLine($"Message:{ex.Message}");
|
||||
message.AppendLine($"Type: {ex.GetType()}");
|
||||
message.AppendLine("StackTrace:");
|
||||
message.AppendLine(ex.StackTrace);
|
||||
if (ex.InnerException != null)
|
||||
{
|
||||
message.AppendLine("InnerException:");
|
||||
message.AppendLine(GetFullErrorMessage(ex.InnerException));
|
||||
}
|
||||
return message.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,6 +292,12 @@ namespace DB2CoreTest.CURD
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true, ColumnDescription = "用户注册日期")]
|
||||
public DateTime? RegistrationDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDescription = "是否启用")]
|
||||
public bool IsActived { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -217,4 +324,20 @@ namespace DB2CoreTest.CURD
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public DateTime LoginTime { get; set; }
|
||||
}
|
||||
|
||||
public class Student
|
||||
{
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// 别名
|
||||
/// </summary>
|
||||
public string Alias { get; set; }
|
||||
/// <summary>
|
||||
/// 启用
|
||||
/// </summary>
|
||||
public bool IsActived { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -8,12 +8,15 @@ public class Program
|
||||
//CodeFirst.Init();
|
||||
CodeFirst.Insertable();
|
||||
CodeFirst.Queryable();
|
||||
CodeFirst.QueryableSelect();
|
||||
CodeFirst.JoinQuery();
|
||||
CodeFirst.PageQuery();
|
||||
CodeFirst.OrderBy();
|
||||
CodeFirst.GroupBy();
|
||||
CodeFirst.Updateable();
|
||||
CodeFirst.Deleteable();
|
||||
|
||||
Console.ReadLine();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,17 +9,17 @@ namespace SqlSugar.DB2
|
||||
public override string GetDbTypeName(string csharpTypeName)
|
||||
{
|
||||
if (csharpTypeName == UtilConstants.ByteArrayType.Name)
|
||||
return "bytea";
|
||||
if (csharpTypeName.ToLower() == "int32")
|
||||
return "varbinary";
|
||||
if (csharpTypeName.ToLower().IsIn("int","int32"))
|
||||
csharpTypeName = "int";
|
||||
if (csharpTypeName.ToLower() == "int16")
|
||||
else if (csharpTypeName.ToLower() == "int16")
|
||||
csharpTypeName = "short";
|
||||
if (csharpTypeName.ToLower() == "int64")
|
||||
else if (csharpTypeName.ToLower() == "int64")
|
||||
csharpTypeName = "long";
|
||||
if (csharpTypeName.ToLower().IsIn("boolean", "bool"))
|
||||
else if (csharpTypeName.ToLower().IsIn("boolean", "bool"))
|
||||
csharpTypeName = "bool";
|
||||
if (csharpTypeName == "DateTimeOffset")
|
||||
csharpTypeName = "DateTime";
|
||||
else if (csharpTypeName.ToLower().IsIn("dateTime","datetimeoffset"))
|
||||
csharpTypeName = "dateTime";
|
||||
var mappings = this.MappingTypes.Where(it => it.Value.ToString().Equals(csharpTypeName, StringComparison.CurrentCultureIgnoreCase)).ToList();
|
||||
if (mappings != null && mappings.Count > 0)
|
||||
return mappings.First().Key;
|
||||
@ -30,22 +30,26 @@ namespace SqlSugar.DB2
|
||||
{
|
||||
dbTypeName = dbTypeName.ToLower();
|
||||
var propertyTypes = MappingTypes.Where(it => it.Value.ToString().ToLower() == dbTypeName || it.Key.ToLower() == dbTypeName);
|
||||
if (propertyTypes == null)
|
||||
if (propertyTypes == null || !propertyTypes.Any())
|
||||
{
|
||||
return "other";
|
||||
return "string";
|
||||
}
|
||||
else if (dbTypeName == "xml" || dbTypeName == "string" || dbTypeName == "jsonb" || dbTypeName == "json")
|
||||
{
|
||||
return "string";
|
||||
}
|
||||
else if (dbTypeName == "bpchar")//数据库char datatype 查询出来的时候是 bpchar
|
||||
else if (dbTypeName == "character")
|
||||
{
|
||||
return "char";
|
||||
}
|
||||
if (dbTypeName == "byte[]")
|
||||
else if (dbTypeName == "byte[]")
|
||||
{
|
||||
return "byte[]";
|
||||
}
|
||||
else if (dbTypeName == "boolean")
|
||||
{
|
||||
return "char";
|
||||
}
|
||||
else if (propertyTypes == null || propertyTypes.Count() == 0)
|
||||
{
|
||||
if (dbTypeName.StartsWith("_"))
|
||||
@ -82,6 +86,8 @@ namespace SqlSugar.DB2
|
||||
}
|
||||
public static List<KeyValuePair<string, CSharpDataType>> MappingTypesConst = new List<KeyValuePair<string, CSharpDataType>>(){
|
||||
|
||||
|
||||
new KeyValuePair<string, CSharpDataType>("boolean",CSharpDataType.@bool),
|
||||
new KeyValuePair<string, CSharpDataType>("varbinary",CSharpDataType.@byteArray),
|
||||
new KeyValuePair<string, CSharpDataType>("binary",CSharpDataType.@byteArray),
|
||||
new KeyValuePair<string, CSharpDataType>("blob",CSharpDataType.@byteArray),
|
||||
@ -89,6 +95,7 @@ namespace SqlSugar.DB2
|
||||
new KeyValuePair<string, CSharpDataType>("varchar",CSharpDataType.@string),
|
||||
new KeyValuePair<string, CSharpDataType>("char",CSharpDataType.@string),
|
||||
new KeyValuePair<string, CSharpDataType>("clob",CSharpDataType.@string),
|
||||
new KeyValuePair<string, CSharpDataType>("vargraphic",CSharpDataType.@string),
|
||||
|
||||
new KeyValuePair<string, CSharpDataType>("timestamp",CSharpDataType.@DateTime),
|
||||
new KeyValuePair<string, CSharpDataType>("date",CSharpDataType.@DateTime),
|
||||
@ -113,5 +120,28 @@ namespace SqlSugar.DB2
|
||||
return new List<string>() { "int32", "datetime", "decimal", "double", "byte" };
|
||||
}
|
||||
}
|
||||
|
||||
public static List<KeyValuePair<string, System.Data.DbType>> MappingDbTypesConst = new List<KeyValuePair<string, System.Data.DbType>>(){
|
||||
|
||||
|
||||
new KeyValuePair<string, System.Data.DbType>("boolean",System.Data.DbType.Boolean),
|
||||
new KeyValuePair<string, System.Data.DbType>("varbinary",System.Data.DbType.Byte),
|
||||
new KeyValuePair<string, System.Data.DbType>("varchar",System.Data.DbType.String),
|
||||
|
||||
new KeyValuePair<string, System.Data.DbType>("date",System.Data.DbType.Date),
|
||||
new KeyValuePair<string, System.Data.DbType>("time",System.Data.DbType.Time),
|
||||
new KeyValuePair<string, System.Data.DbType>("timestamp",System.Data.DbType.DateTime),
|
||||
new KeyValuePair<string, System.Data.DbType>("timestamp",System.Data.DbType.DateTime2),
|
||||
new KeyValuePair<string, System.Data.DbType>("timestamp",System.Data.DbType.DateTimeOffset),
|
||||
|
||||
new KeyValuePair<string, System.Data.DbType>("integer",System.Data.DbType.Int32),
|
||||
new KeyValuePair<string, System.Data.DbType>("smallint",System.Data.DbType.Int16),
|
||||
new KeyValuePair<string, System.Data.DbType>("bigint",System.Data.DbType.Int64),
|
||||
|
||||
new KeyValuePair<string, System.Data.DbType>("float",System.Data.DbType.Single),
|
||||
new KeyValuePair<string, System.Data.DbType>("double",System.Data.DbType.Double),
|
||||
new KeyValuePair<string, System.Data.DbType>("numeric",System.Data.DbType.VarNumeric),
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Linq;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
@ -6,6 +7,11 @@ namespace SqlSugar.DB2
|
||||
{
|
||||
public partial class DB2QueryBuilder : QueryBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// 静态常量标志
|
||||
/// </summary>
|
||||
private string[] constanFlag = new string[] { "@const", "@constan" };
|
||||
|
||||
#region Sql Template
|
||||
public override string PageTempalte
|
||||
{
|
||||
@ -133,11 +139,41 @@ namespace SqlSugar.DB2
|
||||
{
|
||||
result = SubToListMethod(result);
|
||||
}
|
||||
result = ConstanParameterized(result);
|
||||
return result;
|
||||
//return result.Replace("\"", "").ToUpper();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 常量参数化
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private string ConstanParameterized(string selectSql)
|
||||
{
|
||||
var selectParams = selectSql.Split(",").Select(p =>
|
||||
{
|
||||
if (!constanFlag.Any(t => p.ToLower().Contains(t))) return p;
|
||||
var parameter = this.Parameters.FirstOrDefault(t => p.Contains(t.ParameterName));
|
||||
if (parameter == null) return p;
|
||||
|
||||
var dbType = DB2DbBind.MappingDbTypesConst.FirstOrDefault(t => parameter.DbType == t.Value);
|
||||
if (default(KeyValuePair<string, System.Data.DbType>).Equals(dbType)) return p;
|
||||
var parameterized = string.Empty;
|
||||
if (dbType.Value == System.Data.DbType.String)
|
||||
{
|
||||
var size = string.IsNullOrEmpty(parameter.Value?.ToString()) ? 1 : System.Text.Encoding.Default.GetBytes(parameter.Value?.ToString()).Length;;
|
||||
parameterized = $"{dbType.Key.ToUpper()}({size})";
|
||||
}
|
||||
else
|
||||
{
|
||||
parameterized = $"{dbType.Key.ToUpper()}";
|
||||
}
|
||||
return p.Replace(parameter.ParameterName, $" CAST({parameter.ParameterName} AS {parameterized}) ");
|
||||
});
|
||||
return string.Join(",", selectParams);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Net.IBM.Data.Db2" Version="8.0.0.300" />
|
||||
<PackageReference Include="Net.IBM.Data.Db2" Version="8.0.0.310" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
Loading…
Reference in New Issue
Block a user