From df07b7bcc4b6cfb16ced1566c0e0b1dc3e320a4f Mon Sep 17 00:00:00 2001
From: 28810 <28810@YEXIANGQIN>
Date: Wed, 19 Dec 2018 12:06:04 +0800
Subject: [PATCH 1/6] =?UTF-8?q?SqlServer=20CodeFirst=20=E9=80=82=E9=85=8D?=
=?UTF-8?q?=E5=AE=8C=E6=88=90=EF=BC=88=E5=90=8C=E6=AD=A5=E7=BB=93=E6=9E=84?=
=?UTF-8?q?=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Docs/codefirst.md | 16 +---
.../Generator/MySqlTemplateGeneratorTest.cs | 2 +-
.../SqlServer/SqlServerCodeFirstTest.cs | 70 +++++++++++++++++
FreeSql.Tests/g.cs | 3 +-
FreeSql/MySql/MySqlDbFirst.cs | 10 +++
FreeSql/PostgreSQL/PostgreSQLDbFirst.cs | 10 +++
FreeSql/SqlServer/SqlServerCodeFirst.cs | 77 +++++++++++--------
FreeSql/SqlServer/SqlServerDbFirst.cs | 10 +++
.../Models/for-table.cs.freesql | 3 +-
9 files changed, 153 insertions(+), 48 deletions(-)
create mode 100644 FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs
diff --git a/Docs/codefirst.md b/Docs/codefirst.md
index 0bafd459..46ef96a8 100644
--- a/Docs/codefirst.md
+++ b/Docs/codefirst.md
@@ -1,18 +1,10 @@
# CodeFirst
-### 支持的类型
+| 数据库 | 支持的类型类型 |
+| - | - |
+| MySql | bool, sbyte, short, int, long, byte, ushort, uint, ulong, double, float, decimal, Guid, TimeSpan, DateTime
bool?, sbyte?, short?, int?, long?, byte?, ushort?, uint?, ulong?, double?, float?, decimal?, Guid?, TimeSpan?, DateTime?
byte[], string, Enum & FlagsEnum
MygisPoint, MygisLineString, MygisPolygon, MygisMultiPoint, MygisMultiLineString, MygisMultiPolygon |
+| SqlServer | bool, sbyte, short, int, long, byte, ushort, uint, ulong, double, float, decimal, Guid, TimeSpan, DateTime, DateTimeOffset
bool?, sbyte?, short?, int?, long?, byte?, ushort?, uint?, ulong?, double?, float?, decimal?, Guid?, TimeSpan?, DateTime?, DateTimeOffset?
byte[], string, Enum & FlagsEnum |
-bool, byte, short, int, long, byte, ushort, uint, ulong, double, float, decimal, int, Guid
-
-bool?, byte?, short?, int?, long?, byte?, ushort?, uint?, ulong?, double?, float?, decimal?, int?, Guid?
-
-TimeSpan, DateTime
-
-TimeSpan?, DateTime?
-
-byte[], string
-
-MygisPoint, MygisLineString, MygisPolygon, MygisMultiPoint, MygisMultiLineString, MygisMultiPolygon
```csharp
IFreeSql fsql = new FreeSql.FreeSqlBuilder()
diff --git a/FreeSql.Tests/Generator/MySqlTemplateGeneratorTest.cs b/FreeSql.Tests/Generator/MySqlTemplateGeneratorTest.cs
index ff0e085b..51d97a35 100644
--- a/FreeSql.Tests/Generator/MySqlTemplateGeneratorTest.cs
+++ b/FreeSql.Tests/Generator/MySqlTemplateGeneratorTest.cs
@@ -21,7 +21,7 @@ namespace FreeSql.Tests.Generator {
[Fact]
public void BuildRichEntityNavigationObject() {
var gen = new TemplateGenerator();
- gen.Build(g.mysql.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\rich-entity-navigation-object", @"C:\Users\28810\Desktop\新建文件夹 (9)", "cccddd");
+ gen.Build(g.mysql.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\rich-entity-navigation-object", @"C:\Users\28810\Desktop\新建文件夹 (9)", "ManagerDB");
}
}
}
diff --git a/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs
new file mode 100644
index 00000000..96785091
--- /dev/null
+++ b/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs
@@ -0,0 +1,70 @@
+using FreeSql.DataAnnotations;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace FreeSql.Tests.SqlServer {
+ public class SqlServerCodeFirstTest {
+ [Fact]
+ public void GetComparisonDDLStatements() {
+
+ var sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements();
+
+
+ }
+
+
+ [Table(Name = "tb_alltype")]
+ class TableAllType {
+ [Column(IsIdentity = true, IsPrimary = true)]
+ public int Id { get; set; }
+
+ [Column(OldName = "testFieldBool1111")]
+ public bool testFieldBool { get; set; }
+ public sbyte testFieldSByte { get; set; }
+ public short testFieldShort { get; set; }
+ public int testFieldInt { get; set; }
+ public long testFieldLong { get; set; }
+ public byte testFieldByte { get; set; }
+ public ushort testFieldUShort { get; set; }
+ public uint testFieldUInt { get; set; }
+ public ulong testFieldULong { get; set; }
+ public double testFieldDouble { get; set; }
+ public float testFieldFloat { get; set; }
+ public decimal testFieldDecimal { get; set; }
+ public TimeSpan testFieldTimeSpan { get; set; }
+ public DateTime testFieldDateTime { get; set; }
+ public DateTimeOffset testFieldDateTimeOffset { get; set; }
+ public byte[] testFieldBytes { get; set; }
+ public string testFieldString { get; set; }
+ public Guid testFieldGuid { get; set; }
+
+ public bool? testFieldBoolNullable { get; set; }
+ public sbyte? testFieldSByteNullable { get; set; }
+ public short? testFieldShortNullable { get; set; }
+ public int? testFieldIntNullable { get; set; }
+ public long? testFielLongNullable { get; set; }
+ public byte? testFieldByteNullable { get; set; }
+ public ushort? testFieldUShortNullable { get; set; }
+ public uint? testFieldUIntNullable { get; set; }
+ public ulong? testFieldULongNullable { get; set; }
+ public double? testFieldDoubleNullable { get; set; }
+ public float? testFieldFloatNullable { get; set; }
+ public decimal? testFieldDecimalNullable { get; set; }
+ public TimeSpan? testFieldTimeSpanNullable { get; set; }
+ public DateTime? testFieldDateTimeNullable { get; set; }
+ public DateTimeOffset? testFieldDateTimeNullableOffset { get; set; }
+ public Guid? testFieldGuidNullable { get; set; }
+
+ public TableAllTypeEnumType1 testFieldEnum1 { get; set; }
+ public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; }
+ public TableAllTypeEnumType2 testFieldEnum2 { get; set; }
+ public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; }
+ }
+
+ public enum TableAllTypeEnumType1 { e1, e2, e3, e5 }
+ [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 }
+ }
+}
diff --git a/FreeSql.Tests/g.cs b/FreeSql.Tests/g.cs
index 1f7f39b0..9ca30775 100644
--- a/FreeSql.Tests/g.cs
+++ b/FreeSql.Tests/g.cs
@@ -6,7 +6,8 @@ using System.Text;
public class g {
public static IFreeSql mysql = new FreeSql.FreeSqlBuilder()
- .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10")
+ //.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10")
+ .UseConnectionString(FreeSql.DataType.MySql, "Data Source=123.207.16.102;Port=3306;User ID=root;Password=qwe369258/*-;Initial Catalog=ManagerDB;Charset=utf8;SslMode=none;Max pool size=10")
.Build();
public static IFreeSql sqlserver = new FreeSql.FreeSqlBuilder()
diff --git a/FreeSql/MySql/MySqlDbFirst.cs b/FreeSql/MySql/MySqlDbFirst.cs
index 942c52ba..af4e4db1 100644
--- a/FreeSql/MySql/MySqlDbFirst.cs
+++ b/FreeSql/MySql/MySqlDbFirst.cs
@@ -358,6 +358,16 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(posi
if (ret == 0) ret = t1.Name.CompareTo(t2.Name);
return ret;
});
+ foreach(var loc4 in loc1) {
+ var dicUniques = new Dictionary>();
+ dicUniques.Add(string.Join(",", loc4.Primarys.Select(a => a.Name)), loc4.Primarys);
+ foreach(var loc5 in loc4.Uniques) {
+ var dickey = string.Join(",", loc5.Select(a => a.Name));
+ if (dicUniques.ContainsKey(dickey)) continue;
+ dicUniques.Add(dickey, loc5);
+ }
+ loc4.Uniques = dicUniques.Values.ToList();
+ }
loc2.Clear();
loc3.Clear();
diff --git a/FreeSql/PostgreSQL/PostgreSQLDbFirst.cs b/FreeSql/PostgreSQL/PostgreSQLDbFirst.cs
index f232571d..bbff5851 100644
--- a/FreeSql/PostgreSQL/PostgreSQLDbFirst.cs
+++ b/FreeSql/PostgreSQL/PostgreSQLDbFirst.cs
@@ -357,6 +357,16 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(posi
if (ret == 0) ret = t1.Name.CompareTo(t2.Name);
return ret;
});
+ foreach (var loc4 in loc1) {
+ var dicUniques = new Dictionary>();
+ dicUniques.Add(string.Join(",", loc4.Primarys.Select(a => a.Name)), loc4.Primarys);
+ foreach (var loc5 in loc4.Uniques) {
+ var dickey = string.Join(",", loc5.Select(a => a.Name));
+ if (dicUniques.ContainsKey(dickey)) continue;
+ dicUniques.Add(dickey, loc5);
+ }
+ loc4.Uniques = dicUniques.Values.ToList();
+ }
loc2.Clear();
loc3.Clear();
diff --git a/FreeSql/SqlServer/SqlServerCodeFirst.cs b/FreeSql/SqlServer/SqlServerCodeFirst.cs
index 49fda5d8..8d648818 100644
--- a/FreeSql/SqlServer/SqlServerCodeFirst.cs
+++ b/FreeSql/SqlServer/SqlServerCodeFirst.cs
@@ -22,40 +22,51 @@ namespace FreeSql.SqlServer {
public bool IsAutoSyncStructure { get; set; } = true;
- static readonly Dictionary _dicCsToDb = new Dictionary() {
- { "System.Boolean", (SqlDbType.Bit, "bit","bit NOT NULL", null, false) },{ "System.Nullable`1[System.Boolean]", (SqlDbType.Bit, "bit","bit", null, true) },
+ static object _dicCsToDbLock = new object();
+ static Dictionary _dicCsToDb = new Dictionary() {
+ { typeof(bool).FullName, (SqlDbType.Bit, "bit","bit NOT NULL", null, false) },{ typeof(bool?).FullName, (SqlDbType.Bit, "bit","bit", null, true) },
- { "System.SByte", (SqlDbType.TinyInt, "tinyint", "tinyint NOT NULL", false, false) },{ "System.Nullable`1[System.SByte]", (SqlDbType.TinyInt, "tinyint", "tinyint", false, true) },
- { "System.Int16", (SqlDbType.SmallInt, "smallint","smallint NOT NULL", false, false) },{ "System.Nullable`1[System.Int16]", (SqlDbType.SmallInt, "smallint", "smallint", false, true) },
- { "System.Int32", (SqlDbType.Int, "int", "int NOT NULL", false, false) },{ "System.Nullable`1[System.Int32]", (SqlDbType.Int, "int", "int", false, true) },
- { "System.Int64", (SqlDbType.BigInt, "bigint","bigint NOT NULL", false, false) },{ "System.Nullable`1[System.Int64]", (SqlDbType.BigInt, "bigint","bigint", false, true) },
+ { typeof(sbyte).FullName, (SqlDbType.TinyInt, "tinyint", "tinyint NOT NULL", false, false) },{ typeof(sbyte?).FullName, (SqlDbType.TinyInt, "tinyint", "tinyint", false, true) },
+ { typeof(short).FullName, (SqlDbType.SmallInt, "smallint","smallint NOT NULL", false, false) },{ typeof(short?).FullName, (SqlDbType.SmallInt, "smallint", "smallint", false, true) },
+ { typeof(int).FullName, (SqlDbType.Int, "int", "int NOT NULL", false, false) },{ typeof(int?).FullName, (SqlDbType.Int, "int", "int", false, true) },
+ { typeof(long).FullName, (SqlDbType.BigInt, "bigint","bigint NOT NULL", false, false) },{ typeof(long?).FullName, (SqlDbType.BigInt, "bigint","bigint", false, true) },
- { "System.Byte", (SqlDbType.TinyInt, "tinyint","tinyint NOT NULL", true, false) },{ "System.Nullable`1[System.Byte]", (SqlDbType.TinyInt, "tinyint","tinyint", true, true) },
- { "System.UInt16", (SqlDbType.SmallInt, "smallint","smallint NOT NULL", true, false) },{ "System.Nullable`1[System.UInt16]", (SqlDbType.SmallInt, "smallint", "smallint", true, true) },
- { "System.UInt32", (SqlDbType.Int, "int", "int NOT NULL", true, false) },{ "System.Nullable`1[System.UInt32]", (SqlDbType.Int, "int", "int", true, true) },
- { "System.UInt64", (SqlDbType.BigInt, "bigint", "bigint NOT NULL", true, false) },{ "System.Nullable`1[System.UInt64]", (SqlDbType.BigInt, "bigint", "bigint", true, true) },
+ { typeof(byte).FullName, (SqlDbType.TinyInt, "tinyint","tinyint NOT NULL", true, false) },{ typeof(byte?).FullName, (SqlDbType.TinyInt, "tinyint","tinyint", true, true) },
+ { typeof(ushort).FullName, (SqlDbType.SmallInt, "smallint","smallint NOT NULL", true, false) },{ typeof(ushort?).FullName, (SqlDbType.SmallInt, "smallint", "smallint", true, true) },
+ { typeof(uint).FullName, (SqlDbType.Int, "int", "int NOT NULL", true, false) },{ typeof(uint?).FullName, (SqlDbType.Int, "int", "int", true, true) },
+ { typeof(ulong).FullName, (SqlDbType.BigInt, "bigint", "bigint NOT NULL", true, false) },{ typeof(ulong?).FullName, (SqlDbType.BigInt, "bigint", "bigint", true, true) },
- { "System.Double", (SqlDbType.Float, "double", "double NOT NULL", false, false) },{ "System.Nullable`1[System.Double]", (SqlDbType.Float, "double", "double", false, true) },
- { "System.Single", (SqlDbType.Real, "float","float NOT NULL", false, false) },{ "System.Nullable`1[System.Single]", (SqlDbType.Real, "float","float", false, true) },
- { "System.Decimal", (SqlDbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false) },{ "System.Nullable`1[System.Decimal]", (SqlDbType.Decimal, "decimal", "decimal(10,2)", false, true) },
+ { typeof(double).FullName, (SqlDbType.Float, "float", "float NOT NULL", false, false) },{ typeof(double?).FullName, (SqlDbType.Float, "float", "float", false, true) },
+ { typeof(float).FullName, (SqlDbType.Real, "real","real NOT NULL", false, false) },{ typeof(float?).FullName, (SqlDbType.Real, "real","real", false, true) },
+ { typeof(decimal).FullName, (SqlDbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false) },{ typeof(decimal?).FullName, (SqlDbType.Decimal, "decimal", "decimal(10,2)", false, true) },
- { "System.TimeSpan", (SqlDbType.Time, "time","time NOT NULL", false, false) },{ "System.Nullable`1[System.TimeSpan]", (SqlDbType.Time, "time", "time",false, true) },
- { "System.DateTime", (SqlDbType.DateTime, "datetime", "datetime NOT NULL", false, false) },{ "System.Nullable`1[System.DateTime]", (SqlDbType.DateTime, "datetime", "datetime", false, true) },
- { "System.DateTimeOffset", (SqlDbType.DateTimeOffset, "datetimeoffset", "datetimeoffset NOT NULL", false, false) },{ "System.Nullable`1[System.DateTime]", (SqlDbType.DateTimeOffset, "datetimeoffset", "datetimeoffset", false, true) },
+ { typeof(TimeSpan).FullName, (SqlDbType.Time, "time","time NOT NULL", false, false) },{ typeof(TimeSpan?).FullName, (SqlDbType.Time, "time", "time",false, true) },
+ { typeof(DateTime).FullName, (SqlDbType.DateTime, "datetime", "datetime NOT NULL", false, false) },{ typeof(DateTime?).FullName, (SqlDbType.DateTime, "datetime", "datetime", false, true) },
+ { typeof(DateTimeOffset).FullName, (SqlDbType.DateTimeOffset, "datetimeoffset", "datetimeoffset NOT NULL", false, false) },{ typeof(DateTimeOffset?).FullName, (SqlDbType.DateTimeOffset, "datetimeoffset", "datetimeoffset", false, true) },
- { "System.Byte[]", (SqlDbType.VarBinary, "varbinary", "varbinary(255)", false, null) },
- { "System.String", (SqlDbType.NVarChar, "nvarchar", "nvarchar(255)", false, null) },
+ { typeof(byte[]).FullName, (SqlDbType.VarBinary, "varbinary", "varbinary(255)", false, null) },
+ { typeof(string).FullName, (SqlDbType.NVarChar, "nvarchar", "nvarchar(255)", false, null) },
- { "System.Guid", (SqlDbType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier", false, false) },{ "System.Guid", (SqlDbType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier", false, true) },
+ { typeof(Guid).FullName, (SqlDbType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier NOT NULL", false, false) },{ typeof(Guid?).FullName, (SqlDbType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier", false, true) },
};
public (int type, string dbtype, string dbtypeFull, bool? isnullable)? GetDbInfo(Type type) {
+ if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable));
var enumType = type.IsEnum ? type : null;
if (enumType == null && type.FullName.StartsWith("System.Nullable`1[") && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First();
if (enumType != null) {
- return ((int)SqlDbType.Int, "int", "int", type.IsEnum ? false : true);
+ var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ?
+ (SqlDbType.BigInt, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true) :
+ (SqlDbType.Int, "int", $"int{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true);
+ if (_dicCsToDb.ContainsKey(type.FullName) == false) {
+ lock (_dicCsToDbLock) {
+ if (_dicCsToDb.ContainsKey(type.FullName) == false)
+ _dicCsToDb.Add(type.FullName, newItem);
+ }
+ }
+ return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5);
}
- return _dicCsToDb.TryGetValue(type.FullName, out var trydc) ? new (int, string, string, bool?)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable)) : null;
+ return null;
}
public string GetComparisonDDLStatements() => this.GetComparisonDDLStatements(typeof(TEntity));
@@ -70,11 +81,11 @@ namespace FreeSql.SqlServer {
var isRenameTable = false;
var tbname = tb.DbName.Split(new[] { '.' }, 2);
if (tbname.Length == 1) tbname = new[] { "dbo", tbname[0] };
- if (_orm.Ado.ExecuteScalar(CommandType.Text, "select 1 from dbo.sysobjects where id = object_id(N'[{0}].[{1}]') and OBJECTPROPERTY(id, N'IsUserTable')".FormatMySql(tbname)) == null) { //表不存在
+ if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format("select 1 from dbo.sysobjects where id = object_id(N'[{0}].[{1}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1", tbname)) == null) { //表不存在
- if (tboldname != null && _orm.Ado.ExecuteScalar(CommandType.Text, "select 1 from dbo.sysobjects where id = object_id(N'[{0}].[{1}]') and OBJECTPROPERTY(id, N'IsUserTable')".FormatMySql(tboldname)) != null) { //旧表存在
+ if (tboldname != null && _orm.Ado.ExecuteScalar(CommandType.Text, string.Format("select 1 from dbo.sysobjects where id = object_id(N'[{0}].[{1}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1", tboldname)) != null) { //旧表存在
//修改表名
- sb.Append(_commonUtils.FormatSql("EXEC sp_rename {0}, {1} GO \r\n", _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"), _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")));
+ sb.Append(_commonUtils.FormatSql("EXEC sp_rename {0}, {1} \r\nGO \r\n", _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"), _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")));
isRenameTable = true;
} else {
@@ -87,7 +98,7 @@ namespace FreeSql.SqlServer {
if (tbcol.Attribute.IsPrimary) sb.Append(" primary key");
sb.Append(",");
}
- sb.Remove(sb.Length - 1, 1).Append("\r\n) GO \r\n");
+ sb.Remove(sb.Length - 1, 1).Append("\r\n) \r\nGO \r\n");
continue;
}
}
@@ -96,7 +107,7 @@ namespace FreeSql.SqlServer {
foreach (var tbcol in tb.Columns) addcols.Add(tbcol.Value.Attribute.Name, tbcol.Value);
var surplus = new Dictionary(StringComparer.CurrentCultureIgnoreCase);
var dbcols = new List();
- var sql = @"select
+ var sql = string.Format(@"select
a.name 'Column'
,b.name + case
when b.name in ('Char', 'VarChar', 'NChar', 'NVarChar', 'Binary', 'VarBinary') then '(' +
@@ -105,14 +116,14 @@ a.name 'Column'
else cast(a.max_length as varchar) end + ')'
when b.name in ('Numeric', 'Decimal') then '(' + cast(a.precision as varchar) + ',' + cast(a.scale as varchar) + ')'
else '' end as 'SqlType'
-,a.is_nullable 'IsNullable'
-,a.is_identity 'IsIdentity'
+,case when a.is_nullable = 1 then '1' else '0' end 'IsNullable'
+,case when a.is_identity = 1 then '1' else '0' end 'IsIdentity'
from sys.columns a
inner join sys.types b on b.user_type_id = a.user_type_id
left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.column_id
left join sys.tables d on d.object_id = a.object_id
left join sys.schemas e on e.schema_id = d.schema_id
-where a.object_id in (object_id(N'[{0}].[{1}]'))".FormatMySql(isRenameTable ? tboldname : tbname);
+where a.object_id in (object_id(N'[{0}].[{1}]'))", isRenameTable ? tboldname : tbname);
var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
foreach (var row in ds) {
string column = string.Concat(row[0]);
@@ -126,7 +137,7 @@ where a.object_id in (object_id(N'[{0}].[{1}]'))".FormatMySql(isRenameTable ? tb
trycol.Attribute.IsIdentity != is_identity) {
sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(column)).Append(" ").Append(trycol.Attribute.DbType.ToUpper());
if (trycol.Attribute.IsIdentity && trycol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)");
- sb.Append(" GO \r\n");
+ sb.Append(" \r\nGO \r\n");
}
addcols.Remove(column);
} else
@@ -134,15 +145,15 @@ where a.object_id in (object_id(N'[{0}].[{1}]'))".FormatMySql(isRenameTable ? tb
}
foreach (var addcol in addcols.Values) {
if (string.IsNullOrEmpty(addcol.Attribute.OldName) == false && surplus.ContainsKey(addcol.Attribute.OldName)) { //修改列名
- sb.Append(_commonUtils.FormatSql("EXEC sp_rename {0}, {1}, 'COLUMN' GO \r\n", _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{addcol.Attribute.OldName}"), _commonUtils.QuoteSqlName(addcol.Attribute.Name)));
+ sb.Append(_commonUtils.FormatSql("EXEC sp_rename {0}, {1}, 'COLUMN' \r\nGO \r\n", $"{tbname[0]}.{tbname[1]}.{addcol.Attribute.OldName}", addcol.Attribute.Name));
sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(addcol.Attribute.Name)).Append(" ").Append(addcol.Attribute.DbType.ToUpper());
if (addcol.Attribute.IsIdentity && addcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)");
- sb.Append(" GO \r\n");
+ sb.Append(" \r\nGO \r\n");
} else { //添加列
sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(addcol.Attribute.Name)).Append(" ").Append(addcol.Attribute.DbType.ToUpper());
if (addcol.Attribute.IsIdentity && addcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)");
- sb.Append(" GO \r\n");
+ sb.Append(" \r\nGO \r\n");
}
}
}
diff --git a/FreeSql/SqlServer/SqlServerDbFirst.cs b/FreeSql/SqlServer/SqlServerDbFirst.cs
index e57c2037..361d0761 100644
--- a/FreeSql/SqlServer/SqlServerDbFirst.cs
+++ b/FreeSql/SqlServer/SqlServerDbFirst.cs
@@ -374,6 +374,16 @@ where b.object_id in ({0})
if (ret == 0) ret = t1.Name.CompareTo(t2.Name);
return ret;
});
+ foreach (var loc4 in loc1) {
+ var dicUniques = new Dictionary>();
+ dicUniques.Add(string.Join(",", loc4.Primarys.Select(a => a.Name)), loc4.Primarys);
+ foreach (var loc5 in loc4.Uniques) {
+ var dickey = string.Join(",", loc5.Select(a => a.Name));
+ if (dicUniques.ContainsKey(dickey)) continue;
+ dicUniques.Add(dickey, loc5);
+ }
+ loc4.Uniques = dicUniques.Values.ToList();
+ }
loc2.Clear();
loc3.Clear();
diff --git a/Templates/MySql/rich-entity-navigation-object/Models/for-table.cs.freesql b/Templates/MySql/rich-entity-navigation-object/Models/for-table.cs.freesql
index e9be6c3a..a33178b3 100644
--- a/Templates/MySql/rich-entity-navigation-object/Models/for-table.cs.freesql
+++ b/Templates/MySql/rich-entity-navigation-object/Models/for-table.cs.freesql
@@ -231,7 +231,8 @@ namespace test.Model {
var affrows = mysql.Update<{#UString(table.Name)}>().Where(a => {#parmsByWhereLambda}).ExecuteAffrows();
if (affrows > 0) return;
}{/if}
- {if pks.Count > 0}this.{#UString(idensCol.Name)} = {#GetCsType(idensCol).Replace("?", "") == "long" ? "" : ("(" + GetCsType(idensCol) + ")")}mysql.Insert<{#UString(table.Name)}>().AppendData(this).ExecuteIdentity();{else}mysql.Insert<{#UString(table.Name)}>().AppendData(this).ExecuteAffrows();{/if}
+ {if idens > 0}this.{#UString(idensCol.Name)} = {#GetCsType(idensCol).Replace("?", "") == "long" ? "" : ("(" + GetCsType(idensCol) + ")")}mysql.Insert<{#UString(table.Name)}>().AppendData(this).ExecuteIdentity();{else}
+ mysql.Insert<{#UString(table.Name)}>().AppendData(this).ExecuteAffrows();{/if}
}
{/if}
}
From 751b2405330e147300fdd4fbe192e1379c00465a Mon Sep 17 00:00:00 2001
From: 28810 <28810@YEXIANGQIN>
Date: Wed, 19 Dec 2018 12:06:54 +0800
Subject: [PATCH 2/6] =?UTF-8?q?SqlServer=20CodeFirst=20=E9=80=82=E9=85=8D?=
=?UTF-8?q?=E5=AE=8C=E6=88=90?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
FreeSql.Tests/g.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/FreeSql.Tests/g.cs b/FreeSql.Tests/g.cs
index 9ca30775..1f7f39b0 100644
--- a/FreeSql.Tests/g.cs
+++ b/FreeSql.Tests/g.cs
@@ -6,8 +6,7 @@ using System.Text;
public class g {
public static IFreeSql mysql = new FreeSql.FreeSqlBuilder()
- //.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10")
- .UseConnectionString(FreeSql.DataType.MySql, "Data Source=123.207.16.102;Port=3306;User ID=root;Password=qwe369258/*-;Initial Catalog=ManagerDB;Charset=utf8;SslMode=none;Max pool size=10")
+ .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10")
.Build();
public static IFreeSql sqlserver = new FreeSql.FreeSqlBuilder()
From d619d29cfa00bde9f019857505c091d2b97c249a Mon Sep 17 00:00:00 2001
From: 28810 <28810@YEXIANGQIN>
Date: Wed, 19 Dec 2018 15:17:44 +0800
Subject: [PATCH 3/6] =?UTF-8?q?sqlserver=20CodeFirst=20DbFirst=20=E6=B5=8B?=
=?UTF-8?q?=E8=AF=95=E9=80=9A=E8=BF=87?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
FreeSql.Tests/Class1.cs | 127 +-----
.../Generator/MySqlTemplateGeneratorTest.cs | 2 +-
.../SqlServerTemplateGeneratorTest.cs | 27 ++
.../SqlServer/SqlServerCodeFirstTest.cs | 164 +++++++-
.../SqlServer/SqlServerDbFirstTest.cs | 21 +
FreeSql/Generator/TemplateGenerator.cs | 1 +
FreeSql/MySql/MySqlDbFirst.cs | 2 +-
FreeSql/PostgreSQL/PostgreSQLDbFirst.cs | 2 +-
FreeSql/SqlServer/SqlServerDbFirst.cs | 377 +++++++++---------
.../{Models => Model}/for-table.cs.freesql | 44 +-
.../rich-entity-navigation-object/readme.md | 94 +++++
.../{Models => Model}/for-table.cs.freesql | 0
.../simple-entity-navigation-object/readme.md | 94 +++++
.../{Models => Model}/for-table.cs.freesql | 0
Templates/MySql/simple-entity/readme.md | 94 +++++
.../rich-entity-navigation-object/Const.cs | 5 +
.../Model/for-table.cs.freesql | 240 +++++++++++
.../rich-entity-navigation-object/readme.md | 94 +++++
.../Model/for-table.cs.freesql | 59 +++
.../simple-entity-navigation-object/readme.md | 94 +++++
.../simple-entity/Model/for-table.cs.freesql | 33 ++
Templates/SqlServer/simple-entity/readme.md | 94 +++++
22 files changed, 1336 insertions(+), 332 deletions(-)
create mode 100644 FreeSql.Tests/Generator/SqlServerTemplateGeneratorTest.cs
create mode 100644 FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs
rename Templates/MySql/rich-entity-navigation-object/{Models => Model}/for-table.cs.freesql (85%)
rename Templates/MySql/simple-entity-navigation-object/{Models => Model}/for-table.cs.freesql (100%)
rename Templates/MySql/simple-entity/{Models => Model}/for-table.cs.freesql (100%)
create mode 100644 Templates/SqlServer/rich-entity-navigation-object/Const.cs
create mode 100644 Templates/SqlServer/rich-entity-navigation-object/Model/for-table.cs.freesql
create mode 100644 Templates/SqlServer/rich-entity-navigation-object/readme.md
create mode 100644 Templates/SqlServer/simple-entity-navigation-object/Model/for-table.cs.freesql
create mode 100644 Templates/SqlServer/simple-entity-navigation-object/readme.md
create mode 100644 Templates/SqlServer/simple-entity/Model/for-table.cs.freesql
create mode 100644 Templates/SqlServer/simple-entity/readme.md
diff --git a/FreeSql.Tests/Class1.cs b/FreeSql.Tests/Class1.cs
index da9da817..5f282702 100644
--- a/FreeSql.Tests/Class1.cs
+++ b/FreeSql.Tests/Class1.cs
@@ -1,126 +1 @@
-
-//using System;
-//using System.Collections;
-//using System.Collections.Generic;
-//using System.Linq;
-//using System.Text;
-//using System.Text.RegularExpressions;
-//using FreeSql;
-//using FreeSql.DatabaseModel;
-
-////namespace TplDynamicCodeGenerate {
-//public class TplDynamicCodeGenerate_view1 : FreeSql.Generator.TemplateEngin.ITemplateOutput {
-// public FreeSql.Generator.TemplateEngin.TemplateReturnInfo OuTpUt(StringBuilder tOuTpUt, IDictionary oPtIoNs, string rEfErErFiLeNaMe, FreeSql.Generator.TemplateEngin tEmPlAtEsEnDeR) {
-// FreeSql.Generator.TemplateEngin.TemplateReturnInfo rTn = tOuTpUt == null ?
-// new FreeSql.Generator.TemplateEngin.TemplateReturnInfo { Sb = (tOuTpUt = new StringBuilder()), Blocks = new Dictionary() } :
-// new FreeSql.Generator.TemplateEngin.TemplateReturnInfo { Sb = tOuTpUt, Blocks = new Dictionary() };
-// Dictionary TPL__blocks = rTn.Blocks;
-// Stack TPL__blocks_stack = new Stack();
-// int[] TPL__blocks_stack_peek;
-// List TPL__forc = new List();
-// Func pRoCeSsOpTiOnS = new Func(delegate () {
-// IDictionary nEwoPtIoNs = new Hashtable();
-// foreach (DictionaryEntry oPtIoNs_dE in oPtIoNs)
-// nEwoPtIoNs[oPtIoNs_dE.Key] = oPtIoNs_dE.Value;
-// foreach (IDictionary TPL__forc_dIc in TPL__forc)
-// foreach (DictionaryEntry TPL__forc_dIc_dE in TPL__forc_dIc)
-// nEwoPtIoNs[TPL__forc_dIc_dE.Key] = TPL__forc_dIc_dE.Value;
-// return nEwoPtIoNs;
-// });
-// FreeSql.Generator.TemplateEngin.TemplateIf tPlIf = delegate (object exp) {
-// if (exp is bool) return (bool)exp;
-// if (exp == null) return false;
-// if (exp is int && (int)exp == 0) return false;
-// if (exp is string && (string)exp == string.Empty) return false;
-// if (exp is long && (long)exp == 0) return false;
-// if (exp is short && (short)exp == 0) return false;
-// if (exp is byte && (byte)exp == 0) return false;
-// if (exp is double && (double)exp == 0) return false;
-// if (exp is float && (float)exp == 0) return false;
-// if (exp is decimal && (decimal)exp == 0) return false;
-// return true;
-// };
-// FreeSql.Generator.TemplateEngin.TemplatePrint print = delegate (object[] pArMs) {
-// if (pArMs == null || pArMs.Length == 0) return;
-// foreach (object pArMs_A in pArMs) if (pArMs_A != null) tOuTpUt.Append(pArMs_A);
-// };
-// FreeSql.Generator.TemplateEngin.TemplatePrint Print = prin
-// dynamic index = oPtIoNs["index"];
-// dynamic col = oPtIoNs["col"];
-// dynamic table = oPtIoNs["table"];
-// dynamic dbfirst = oPtIoNs["dbfirst"]; t;
-// tOuTpUt.Append("using System;\r\nusing System.Collections;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing System.Reflection;\r\nusing System.Threading.Tasks;\r\nusing Newtonsoft.Json;\r\nusing FreeSql.DataAnnotations;\r\n");
-
-// var dbf = dbfirst as FreeSql.IDbFirst;
-// var cols = (table.Columns as List);
-
-// Func UString = stra => stra.Substring(0, 1).ToUpper() + stra.Substring(1);
-// Func GetCsType = cola3 => {
-// if (cola3.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Enum || cola3.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Set) {
-// return $"{UString(cola3.Table.Name)}{cola3.Name.ToUpper()}{(cola3.IsNullable ? "?" : "")}";
-// }
-// return dbf.GetCsType(cola3);
-// };
-
-// tOuTpUt.Append("\r\nnamespace test.Model {\r\n\r\n [JsonObject(MemberSerialization.OptIn), Table(Name = \"");
-// Print(!string.IsNullOrEmpty(table.Schema) ? table.Schema + "." : "");
-// tOuTpUt.Append("");
-// Print(table.Name);
-// tOuTpUt.Append("\"");
-// if (tPlIf(cols.Where(cola003 => cola003.Name.ToLower() == "is_deleted" || cola003.Name.ToLower() == "isdeleted").Any())) {
-// tOuTpUt.Append(", SelectFilter = \"a.IsDeleted = 1\"");
-// }
-// tOuTpUt.Append(")]\r\n public partial class ");
-// Print(UString(table.Name));
-// tOuTpUt.Append(" {");
-// //new Action(delegate () {
-// IDictionary TPL__tmp1 = new Hashtable();
-// TPL__forc.Add(TPL__tmp1);
-// var TPL__tmp2 = table.Columns;
-// var TPL__tmp3 = col;
-// var TPL__tmp4 = index;
-// index = 0;
-// if (TPL__tmp2 != null)
-// foreach (var TPL__tmp5 in TPL__tmp2) {
-// TPL__tmp1["index"] = ++index;
-// TPL__tmp1["col"] = TPL__tmp5;
-// col = TPL__tmp5;
-// tOuTpUt.Append("\r\n ");
-// if (tPlIf(string.IsNullOrEmpty(col.Coment) == false)) {
-// tOuTpUt.Append("/// \r\n /// ");
-// Print(col.Coment.Replace("\r\n", "\n").Replace("\n", "\r\n /// "));
-// tOuTpUt.Append("\r\n /// ");
-// }
-// tOuTpUt.Append("\r\n [JsonProperty, Column(Name = \"");
-// Print(col.Name);
-// tOuTpUt.Append("\", DbType = \"");
-// Print(col.DbTypeTextFull);
-// tOuTpUt.Append("\"");
-// if (tPlIf(col.IsPrimary == true)) {
-// tOuTpUt.Append(", IsPrimary = true");
-// }
-// tOuTpUt.Append("");
-// if (tPlIf(col.IsIdentity == true)) {
-// tOuTpUt.Append(", IsIdentity = true");
-// }
-// tOuTpUt.Append("");
-// if (tPlIf(col.IsNullable == true)) {
-// tOuTpUt.Append(", IsNullable = true");
-// }
-// tOuTpUt.Append(")]\r\n public ");
-// Print(GetCsType(col));
-// tOuTpUt.Append(" ");
-// Print(UString(col.Name));
-// tOuTpUt.Append(" { get; set; }\r\n ");
-// }
-// col = TPL__tmp3;
-// index = TPL__tmp4;
-// TPL__forc.RemoveAt(TPL__forc.Count - 1);
-// //})();
-// tOuTpUt.Append("\r\n }\r\n");
-// tEmPlAtEsEnDeR.RenderFile2(tOuTpUt, pRoCeSsOpTiOnS(), "../../include/enumtype.tpl", rEfErErFiLeNaMe);
-// tOuTpUt.Append("\r\n}");
-// return rTn;
-// }
-//}
-////}
+
\ No newline at end of file
diff --git a/FreeSql.Tests/Generator/MySqlTemplateGeneratorTest.cs b/FreeSql.Tests/Generator/MySqlTemplateGeneratorTest.cs
index 51d97a35..ff0e085b 100644
--- a/FreeSql.Tests/Generator/MySqlTemplateGeneratorTest.cs
+++ b/FreeSql.Tests/Generator/MySqlTemplateGeneratorTest.cs
@@ -21,7 +21,7 @@ namespace FreeSql.Tests.Generator {
[Fact]
public void BuildRichEntityNavigationObject() {
var gen = new TemplateGenerator();
- gen.Build(g.mysql.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\rich-entity-navigation-object", @"C:\Users\28810\Desktop\新建文件夹 (9)", "ManagerDB");
+ gen.Build(g.mysql.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\rich-entity-navigation-object", @"C:\Users\28810\Desktop\新建文件夹 (9)", "cccddd");
}
}
}
diff --git a/FreeSql.Tests/Generator/SqlServerTemplateGeneratorTest.cs b/FreeSql.Tests/Generator/SqlServerTemplateGeneratorTest.cs
new file mode 100644
index 00000000..759fbb1f
--- /dev/null
+++ b/FreeSql.Tests/Generator/SqlServerTemplateGeneratorTest.cs
@@ -0,0 +1,27 @@
+using FreeSql.DataAnnotations;
+using FreeSql.Generator;
+using System;
+using Xunit;
+
+namespace FreeSql.Tests.Generator {
+ public class SqlServerTemplateGeneratorTest {
+
+ [Fact]
+ public void BuildSimpleEntity() {
+ var gen = new TemplateGenerator();
+ gen.Build(g.sqlserver.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\SqlServer\simple-entity", @"C:\Users\28810\Desktop\新建文件夹 (9)", "shop");
+ }
+
+ [Fact]
+ public void BuildSimpleEntityNavigationObject () {
+ var gen = new TemplateGenerator();
+ gen.Build(g.sqlserver.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\SqlServer\simple-entity-navigation-object", @"C:\Users\28810\Desktop\新建文件夹 (9)", "shop");
+ }
+
+ [Fact]
+ public void BuildRichEntityNavigationObject() {
+ var gen = new TemplateGenerator();
+ gen.Build(g.sqlserver.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\SqlServer\rich-entity-navigation-object", @"C:\Users\28810\Desktop\新建文件夹 (9)", "shop");
+ }
+ }
+}
diff --git a/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs
index 96785091..ec50497a 100644
--- a/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs
+++ b/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs
@@ -11,17 +11,175 @@ namespace FreeSql.Tests.SqlServer {
public void GetComparisonDDLStatements() {
var sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements();
-
+ sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements();
}
+ [JsonObject(MemberSerialization.OptIn), Table(Name = "dbo.tb_alltype")]
+ public partial class Tb_alltype {
- [Table(Name = "tb_alltype")]
+ [JsonProperty, Column(Name = "Id", DbType = "int", IsPrimary = true, IsIdentity = true)]
+ public int Id { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldBool1111", DbType = "bit")]
+ public bool TestFieldBool1111 { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldBoolNullable", DbType = "bit", IsNullable = true)]
+ public bool? TestFieldBoolNullable { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldByte", DbType = "tinyint")]
+ public sbyte TestFieldByte { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldByteNullable", DbType = "tinyint", IsNullable = true)]
+ public sbyte? TestFieldByteNullable { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldBytes", DbType = "varbinary(255)", IsNullable = true)]
+ public byte[] TestFieldBytes { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldDateTime", DbType = "datetime")]
+ public DateTime TestFieldDateTime { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldDateTimeNullable", DbType = "datetime", IsNullable = true)]
+ public DateTime? TestFieldDateTimeNullable { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldDateTimeNullableOffset", DbType = "datetimeoffset", IsNullable = true)]
+ public DateTime? TestFieldDateTimeNullableOffset { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldDateTimeOffset", DbType = "datetimeoffset")]
+ public DateTime TestFieldDateTimeOffset { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldDecimal", DbType = "decimal(10,2)")]
+ public decimal TestFieldDecimal { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldDecimalNullable", DbType = "decimal(10,2)", IsNullable = true)]
+ public decimal? TestFieldDecimalNullable { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldDouble", DbType = "float")]
+ public double TestFieldDouble { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldDoubleNullable", DbType = "float", IsNullable = true)]
+ public double? TestFieldDoubleNullable { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldEnum1", DbType = "int")]
+ public int TestFieldEnum1 { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldEnum1Nullable", DbType = "int", IsNullable = true)]
+ public int? TestFieldEnum1Nullable { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldEnum2", DbType = "bigint")]
+ public long TestFieldEnum2 { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldEnum2Nullable", DbType = "bigint", IsNullable = true)]
+ public long? TestFieldEnum2Nullable { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldFloat", DbType = "real")]
+ public float TestFieldFloat { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldFloatNullable", DbType = "real", IsNullable = true)]
+ public float? TestFieldFloatNullable { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldGuid", DbType = "uniqueidentifier")]
+ public Guid TestFieldGuid { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldGuidNullable", DbType = "uniqueidentifier", IsNullable = true)]
+ public Guid? TestFieldGuidNullable { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldInt", DbType = "int")]
+ public int TestFieldInt { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldIntNullable", DbType = "int", IsNullable = true)]
+ public int? TestFieldIntNullable { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldLong", DbType = "bigint")]
+ public long TestFieldLong { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldSByte", DbType = "tinyint")]
+ public sbyte TestFieldSByte { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldSByteNullable", DbType = "tinyint", IsNullable = true)]
+ public sbyte? TestFieldSByteNullable { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldShort", DbType = "smallint")]
+ public short TestFieldShort { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldShortNullable", DbType = "smallint", IsNullable = true)]
+ public short? TestFieldShortNullable { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldString", DbType = "nvarchar(255)", IsNullable = true)]
+ public string TestFieldString { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldTimeSpan", DbType = "time")]
+ public TimeSpan TestFieldTimeSpan { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldTimeSpanNullable", DbType = "time", IsNullable = true)]
+ public TimeSpan? TestFieldTimeSpanNullable { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldUInt", DbType = "int")]
+ public int TestFieldUInt { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldUIntNullable", DbType = "int", IsNullable = true)]
+ public int? TestFieldUIntNullable { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldULong", DbType = "bigint")]
+ public long TestFieldULong { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldULongNullable", DbType = "bigint", IsNullable = true)]
+ public long? TestFieldULongNullable { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldUShort", DbType = "smallint")]
+ public short TestFieldUShort { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFieldUShortNullable", DbType = "smallint", IsNullable = true)]
+ public short? TestFieldUShortNullable { get; set; }
+
+
+ [JsonProperty, Column(Name = "testFielLongNullable", DbType = "bigint", IsNullable = true)]
+ public long? TestFielLongNullable { get; set; }
+ }
+
+ [Table(Name = "tb_alltype")]
class TableAllType {
[Column(IsIdentity = true, IsPrimary = true)]
public int Id { get; set; }
- [Column(OldName = "testFieldBool1111")]
+ [Column(Name = "testFieldBool1111")]
public bool testFieldBool { get; set; }
public sbyte testFieldSByte { get; set; }
public short testFieldShort { get; set; }
diff --git a/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs b/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs
new file mode 100644
index 00000000..3887afe7
--- /dev/null
+++ b/FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs
@@ -0,0 +1,21 @@
+using FreeSql.DataAnnotations;
+using System;
+using Xunit;
+
+namespace FreeSql.Tests.SqlServer {
+ public class SqlServerDbFirstTest {
+ [Fact]
+ public void GetDatabases() {
+
+ var t1 = g.sqlserver.DbFirst.GetDatabases();
+
+ }
+
+ [Fact]
+ public void GetTablesByDatabase() {
+
+ var t2 = g.sqlserver.DbFirst.GetTablesByDatabase(g.sqlserver.DbFirst.GetDatabases()[0]);
+
+ }
+ }
+}
diff --git a/FreeSql/Generator/TemplateGenerator.cs b/FreeSql/Generator/TemplateGenerator.cs
index 4b0281f3..d97c255e 100644
--- a/FreeSql/Generator/TemplateGenerator.cs
+++ b/FreeSql/Generator/TemplateGenerator.cs
@@ -34,6 +34,7 @@ namespace FreeSql.Generator {
if (fi.Name.StartsWith("for-table.")) {
foreach (var table in tables) {
var result = tpl.RenderFile(file, new Dictionary() { { "table", table }, { "dbfirst", dbfirst } });
+ if (result.EndsWith("return;")) continue;
var outputName = table.Name + outputExtension;
var mcls = Regex.Match(result, @"\s+class\s+(\w+)");
if (mcls.Success) outputName = mcls.Groups[1].Value + outputExtension;
diff --git a/FreeSql/MySql/MySqlDbFirst.cs b/FreeSql/MySql/MySqlDbFirst.cs
index af4e4db1..455e27ae 100644
--- a/FreeSql/MySql/MySqlDbFirst.cs
+++ b/FreeSql/MySql/MySqlDbFirst.cs
@@ -360,7 +360,7 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(posi
});
foreach(var loc4 in loc1) {
var dicUniques = new Dictionary>();
- dicUniques.Add(string.Join(",", loc4.Primarys.Select(a => a.Name)), loc4.Primarys);
+ if (loc4.Primarys.Count > 0) dicUniques.Add(string.Join(",", loc4.Primarys.Select(a => a.Name)), loc4.Primarys);
foreach(var loc5 in loc4.Uniques) {
var dickey = string.Join(",", loc5.Select(a => a.Name));
if (dicUniques.ContainsKey(dickey)) continue;
diff --git a/FreeSql/PostgreSQL/PostgreSQLDbFirst.cs b/FreeSql/PostgreSQL/PostgreSQLDbFirst.cs
index bbff5851..4325abf3 100644
--- a/FreeSql/PostgreSQL/PostgreSQLDbFirst.cs
+++ b/FreeSql/PostgreSQL/PostgreSQLDbFirst.cs
@@ -359,7 +359,7 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(posi
});
foreach (var loc4 in loc1) {
var dicUniques = new Dictionary>();
- dicUniques.Add(string.Join(",", loc4.Primarys.Select(a => a.Name)), loc4.Primarys);
+ if (loc4.Primarys.Count > 0) dicUniques.Add(string.Join(",", loc4.Primarys.Select(a => a.Name)), loc4.Primarys);
foreach (var loc5 in loc4.Uniques) {
var dickey = string.Join(",", loc5.Select(a => a.Name));
if (dicUniques.ContainsKey(dickey)) continue;
diff --git a/FreeSql/SqlServer/SqlServerDbFirst.cs b/FreeSql/SqlServer/SqlServerDbFirst.cs
index 361d0761..02036f2f 100644
--- a/FreeSql/SqlServer/SqlServerDbFirst.cs
+++ b/FreeSql/SqlServer/SqlServerDbFirst.cs
@@ -60,7 +60,6 @@ namespace FreeSql.SqlServer {
{ (int)SqlDbType.Int, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") },
{ (int)SqlDbType.BigInt, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") },
- { (int)SqlDbType.Decimal, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") },
{ (int)SqlDbType.SmallMoney, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") },
{ (int)SqlDbType.Money, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") },
{ (int)SqlDbType.Decimal, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") },
@@ -86,7 +85,7 @@ namespace FreeSql.SqlServer {
{ (int)SqlDbType.NVarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
{ (int)SqlDbType.NText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
- { (int)SqlDbType.UniqueIdentifier, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "MygisGeometry", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") },
+ { (int)SqlDbType.UniqueIdentifier, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") },
};
public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null;
@@ -104,11 +103,22 @@ namespace FreeSql.SqlServer {
}
public List GetTablesByDatabase(params string[] database) {
- List loc1 = null;
- Dictionary loc2 = new Dictionary();
- Dictionary> loc3 = new Dictionary>();
+ var olddatabase = "";
+ using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) {
+ olddatabase = conn.Value.Database;
+ }
+ var dbs = database?.ToArray() ?? new[] { olddatabase };
+ var tables = new List();
- var sql = @"
+ foreach (var db in dbs) {
+ if (string.IsNullOrEmpty(db)) continue;
+
+ var loc1 = new List();
+ var loc2 = new Dictionary();
+ var loc3 = new Dictionary>();
+
+ var sql = $@"
+use {db};
select
a.Object_id
,b.name 'Owner'
@@ -135,34 +145,37 @@ from sys.procedures a
inner join sys.schemas b on b.schema_id = a.schema_id
where a.type = 'P' and charindex('$NPSP', a.name) = 0 and charindex('diagram', a.name) = 0
order by type desc, b.name, a.name
+;
+use {olddatabase};
";
- var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
- if (ds == null) return loc1;
+ var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
+ if (ds == null) return loc1;
- var loc6 = new List();
- var loc66 = new List();
- foreach (object[] row in ds) {
- int object_id = int.Parse(string.Concat(row[0]));
- var owner = string.Concat(row[1]);
- var table = string.Concat(row[2]);
- Enum.TryParse(string.Concat(row[3]), out var type);
- loc2.Add(object_id, new DbTableInfo { Id = object_id.ToString(), Schema = owner, Name = table, Type = type });
- loc3.Add(object_id, new Dictionary());
- switch (type) {
- case DbTableType.VIEW:
- case DbTableType.TABLE:
- loc6.Add(object_id);
- break;
- case DbTableType.StoreProcedure:
- loc66.Add(object_id);
- break;
+ var loc6 = new List();
+ var loc66 = new List();
+ foreach (object[] row in ds) {
+ int object_id = int.Parse(string.Concat(row[0]));
+ var owner = string.Concat(row[1]);
+ var table = string.Concat(row[2]);
+ Enum.TryParse(string.Concat(row[3]), out var type);
+ loc2.Add(object_id, new DbTableInfo { Id = object_id.ToString(), Schema = owner, Name = table, Type = type });
+ loc3.Add(object_id, new Dictionary());
+ switch (type) {
+ case DbTableType.VIEW:
+ case DbTableType.TABLE:
+ loc6.Add(object_id);
+ break;
+ case DbTableType.StoreProcedure:
+ loc66.Add(object_id);
+ break;
+ }
}
- }
- if (loc6.Count == 0) return loc1;
- var loc8 = string.Join(",", loc6.Select(a => string.Concat(a)));
- var loc88 = string.Join(",", loc66.Select(a => string.Concat(a)));
+ if (loc6.Count == 0) return loc1;
+ var loc8 = string.Join(",", loc6.Select(a => string.Concat(a)));
+ var loc88 = string.Join(",", loc66.Select(a => string.Concat(a)));
+
+ var tsql_place = @"
- var tsql_place = @"
select
isnull(e.name,'') + '.' + isnull(d.name,'')
,a.Object_id
@@ -187,50 +200,52 @@ left join sys.tables d on d.object_id = a.object_id
left join sys.schemas e on e.schema_id = d.schema_id
where a.object_id in ({1})
";
- sql = string.Format(tsql_place, @"
+ sql = string.Format(tsql_place, @"
,a.is_nullable 'IsNullable'
,a.is_identity 'IsIdentity'
from sys.columns", loc8);
- if (loc88.Length > 0) {
- sql += "union all" +
- string.Format(tsql_place.Replace(
- "left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.column_id",
- "left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.parameter_id"), @"
+ if (loc88.Length > 0) {
+ sql += "union all" +
+ string.Format(tsql_place.Replace(
+ "left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.column_id",
+ "left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.parameter_id"), @"
,cast(0 as bit) 'IsNullable'
,a.is_output 'IsIdentity'
from sys.parameters", loc88);
- }
- ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
- if (ds == null) return loc1;
+ }
+ sql = $"use {db};{sql};use {olddatabase}; ";
+ ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
+ if (ds == null) return loc1;
- foreach (object[] row in ds) {
- var table_id = string.Concat(row[0]);
- var object_id = int.Parse(string.Concat(row[1]));
- var column = string.Concat(row[2]);
- var type = string.Concat(row[3]);
- var max_length = int.Parse(string.Concat(row[4]));
- var sqlType = string.Concat(row[5]);
- var comment = string.Concat(row[6]);
- var is_nullable = bool.Parse(string.Concat(row[7]));
- var is_identity = bool.Parse(string.Concat(row[8]));
- if (max_length == 0) max_length = -1;
+ foreach (object[] row in ds) {
+ var table_id = string.Concat(row[0]);
+ var object_id = int.Parse(string.Concat(row[1]));
+ var column = string.Concat(row[2]);
+ var type = string.Concat(row[3]);
+ var max_length = int.Parse(string.Concat(row[4]));
+ var sqlType = string.Concat(row[5]);
+ var comment = string.Concat(row[6]);
+ var is_nullable = bool.Parse(string.Concat(row[7]));
+ var is_identity = bool.Parse(string.Concat(row[8]));
+ if (max_length == 0) max_length = -1;
- loc3[object_id].Add(column, new DbColumnInfo {
- Name = column,
- MaxLength = max_length,
- IsIdentity = is_identity,
- IsNullable = is_nullable,
- IsPrimary = false,
- DbTypeText = type,
- DbTypeTextFull = sqlType,
- Table = loc2[object_id],
- Coment = comment
- });
- loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]);
- loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]);
- }
+ loc3[object_id].Add(column, new DbColumnInfo {
+ Name = column,
+ MaxLength = max_length,
+ IsIdentity = is_identity,
+ IsNullable = is_nullable,
+ IsPrimary = false,
+ DbTypeText = type,
+ DbTypeTextFull = sqlType,
+ Table = loc2[object_id],
+ Coment = comment
+ });
+ loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]);
+ loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]);
+ }
- sql = string.Format(@"
+ sql = $@"
+use {db};
select
a.object_id 'Object_id'
,c.name 'Column'
@@ -242,53 +257,55 @@ select
from sys.index_columns a
inner join sys.indexes b on b.object_id = a.object_id and b.index_id = a.index_id
left join sys.columns c on c.object_id = a.object_id and c.column_id = a.column_id
-where a.object_id in ({0})
-", loc8);
- ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
- if (ds == null) return loc1;
+where a.object_id in ({loc8})
+;
+use {olddatabase};
+";
+ ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
+ if (ds == null) return loc1;
- var indexColumns = new Dictionary>>();
- var uniqueColumns = new Dictionary>>();
- foreach (object[] row in ds) {
- int object_id = int.Parse(string.Concat(row[0]));
- string column = string.Concat(row[1]);
- int index_id = int.Parse(string.Concat(row[2]));
- bool is_unique = bool.Parse(string.Concat(row[3]));
- bool is_primary_key = bool.Parse(string.Concat(row[4]));
- bool is_clustered = bool.Parse(string.Concat(row[5]));
- int is_desc = int.Parse(string.Concat(row[6]));
+ var indexColumns = new Dictionary>>();
+ var uniqueColumns = new Dictionary>>();
+ foreach (object[] row in ds) {
+ int object_id = int.Parse(string.Concat(row[0]));
+ string column = string.Concat(row[1]);
+ int index_id = int.Parse(string.Concat(row[2]));
+ bool is_unique = bool.Parse(string.Concat(row[3]));
+ bool is_primary_key = bool.Parse(string.Concat(row[4]));
+ bool is_clustered = bool.Parse(string.Concat(row[5]));
+ int is_desc = int.Parse(string.Concat(row[6]));
- if (loc3.ContainsKey(object_id) == false || loc3[object_id].ContainsKey(column) == false) continue;
- DbColumnInfo loc9 = loc3[object_id][column];
- if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key;
+ if (loc3.ContainsKey(object_id) == false || loc3[object_id].ContainsKey(column) == false) continue;
+ DbColumnInfo loc9 = loc3[object_id][column];
+ if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key;
- Dictionary> loc10 = null;
- List loc11 = null;
- if (!indexColumns.TryGetValue(object_id, out loc10))
- indexColumns.Add(object_id, loc10 = new Dictionary>());
- if (!loc10.TryGetValue(index_id, out loc11))
- loc10.Add(index_id, loc11 = new List());
- loc11.Add(loc9);
- if (is_unique) {
- if (!uniqueColumns.TryGetValue(object_id, out loc10))
- uniqueColumns.Add(object_id, loc10 = new Dictionary>());
+ Dictionary> loc10 = null;
+ List loc11 = null;
+ if (!indexColumns.TryGetValue(object_id, out loc10))
+ indexColumns.Add(object_id, loc10 = new Dictionary>());
if (!loc10.TryGetValue(index_id, out loc11))
loc10.Add(index_id, loc11 = new List());
loc11.Add(loc9);
+ if (is_unique) {
+ if (!uniqueColumns.TryGetValue(object_id, out loc10))
+ uniqueColumns.Add(object_id, loc10 = new Dictionary>());
+ if (!loc10.TryGetValue(index_id, out loc11))
+ loc10.Add(index_id, loc11 = new List());
+ loc11.Add(loc9);
+ }
}
- }
- foreach (var object_id in indexColumns.Keys) {
- foreach (List columns in indexColumns[object_id].Values)
- loc2[object_id].Indexes.Add(columns);
- }
- foreach (var object_id in uniqueColumns.Keys) {
- foreach (var columns in uniqueColumns[object_id].Values) {
- columns.Sort((c1, c2) => c1.Name.CompareTo(c2.Name));
- loc2[object_id].Uniques.Add(columns);
+ foreach (var object_id in indexColumns.Keys) {
+ foreach (List columns in indexColumns[object_id].Values)
+ loc2[object_id].Indexes.Add(columns);
+ }
+ foreach (var object_id in uniqueColumns.Keys) {
+ foreach (var columns in uniqueColumns[object_id].Values) {
+ columns.Sort((c1, c2) => c1.Name.CompareTo(c2.Name));
+ loc2[object_id].Uniques.Add(columns);
+ }
}
- }
- sql = string.Format(@"
+ sql = $@"
select
b.object_id 'Object_id'
,c.name 'Column'
@@ -302,92 +319,96 @@ from sys.foreign_key_columns a
inner join sys.tables b on b.object_id = a.parent_object_id
inner join sys.columns c on c.object_id = a.parent_object_id and c.column_id = a.parent_column_id
inner join sys.columns d on d.object_id = a.referenced_object_id and d.column_id = a.referenced_column_id
-where b.object_id in ({0})
-", loc8);
- ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
- if (ds == null) return loc1;
+where b.object_id in ({loc8})
+;
+use {olddatabase};
+";
+ ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
+ if (ds == null) return loc1;
- var fkColumns = new Dictionary>();
- foreach (object[] row in ds) {
- int object_id, fk_id, referenced_object_id;
- int.TryParse(string.Concat(row[0]), out object_id);
- var column = string.Concat(row[1]);
- int.TryParse(string.Concat(row[2]), out fk_id);
- int.TryParse(string.Concat(row[3]), out referenced_object_id);
- var is_foreign_key = bool.Parse(string.Concat(row[4]));
- var referenced_column = string.Concat(row[5]);
- var referenced_db = string.Concat(row[6]);
- var referenced_table = string.Concat(row[7]);
- DbColumnInfo loc9 = loc3[object_id][column];
- DbTableInfo loc10 = null;
- DbColumnInfo loc11 = null;
- bool isThisSln = referenced_object_id != 0;
+ var fkColumns = new Dictionary>();
+ foreach (object[] row in ds) {
+ int object_id, fk_id, referenced_object_id;
+ int.TryParse(string.Concat(row[0]), out object_id);
+ var column = string.Concat(row[1]);
+ int.TryParse(string.Concat(row[2]), out fk_id);
+ int.TryParse(string.Concat(row[3]), out referenced_object_id);
+ var is_foreign_key = bool.Parse(string.Concat(row[4]));
+ var referenced_column = string.Concat(row[5]);
+ var referenced_db = string.Concat(row[6]);
+ var referenced_table = string.Concat(row[7]);
+ DbColumnInfo loc9 = loc3[object_id][column];
+ DbTableInfo loc10 = null;
+ DbColumnInfo loc11 = null;
+ bool isThisSln = referenced_object_id != 0;
- if (isThisSln) {
- loc10 = loc2[referenced_object_id];
- loc11 = loc3[referenced_object_id][referenced_column];
- } else {
+ if (isThisSln) {
+ loc10 = loc2[referenced_object_id];
+ loc11 = loc3[referenced_object_id][referenced_column];
+ } else {
+ }
+ Dictionary loc12 = null;
+ DbForeignInfo loc13 = null;
+ if (!fkColumns.TryGetValue(object_id, out loc12))
+ fkColumns.Add(object_id, loc12 = new Dictionary());
+ if (!loc12.TryGetValue(fk_id, out loc13))
+ loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[object_id], ReferencedTable = loc10 });
+ loc13.Columns.Add(loc9);
+ loc13.ReferencedColumns.Add(loc11);
}
- Dictionary loc12 = null;
- DbForeignInfo loc13 = null;
- if (!fkColumns.TryGetValue(object_id, out loc12))
- fkColumns.Add(object_id, loc12 = new Dictionary());
- if (!loc12.TryGetValue(fk_id, out loc13))
- loc12.Add(fk_id, new DbForeignInfo { Table = loc2[object_id], ReferencedTable = loc10 });
- loc13.Columns.Add(loc9);
- loc13.ReferencedColumns.Add(loc11);
- }
- foreach (var table_id in fkColumns.Keys)
- foreach (var fk in fkColumns[table_id].Values)
- loc2[table_id].Foreigns.Add(fk);
+ foreach (var table_id in fkColumns.Keys)
+ foreach (var fk in fkColumns[table_id].Values)
+ loc2[table_id].Foreigns.Add(fk);
- foreach (var table_id in loc3.Keys) {
- foreach (var loc5 in loc3[table_id].Values) {
- loc2[table_id].Columns.Add(loc5);
- if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5);
- if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5);
- }
- }
- foreach (var loc4 in loc2.Values) {
- if (loc4.Primarys.Count == 0 && loc4.Uniques.Count > 0) {
- foreach (var loc5 in loc4.Uniques[0]) {
- loc5.IsPrimary = true;
- loc4.Primarys.Add(loc5);
+ foreach (var table_id in loc3.Keys) {
+ foreach (var loc5 in loc3[table_id].Values) {
+ loc2[table_id].Columns.Add(loc5);
+ if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5);
+ if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5);
}
}
- loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name));
- loc4.Columns.Sort((c1, c2) => {
- int compare = c2.IsPrimary.CompareTo(c1.IsPrimary);
- if (compare == 0) {
- bool b1 = loc4.Foreigns.Find(fk => fk.Columns.Find(c3 => c3.Name == c1.Name) != null) != null;
- bool b2 = loc4.Foreigns.Find(fk => fk.Columns.Find(c3 => c3.Name == c2.Name) != null) != null;
- compare = b2.CompareTo(b1);
+ foreach (var loc4 in loc2.Values) {
+ if (loc4.Primarys.Count == 0 && loc4.Uniques.Count > 0) {
+ foreach (var loc5 in loc4.Uniques[0]) {
+ loc5.IsPrimary = true;
+ loc4.Primarys.Add(loc5);
+ }
}
- if (compare == 0) compare = c1.Name.CompareTo(c2.Name);
- return compare;
+ loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name));
+ loc4.Columns.Sort((c1, c2) => {
+ int compare = c2.IsPrimary.CompareTo(c1.IsPrimary);
+ if (compare == 0) {
+ bool b1 = loc4.Foreigns.Find(fk => fk.Columns.Find(c3 => c3.Name == c1.Name) != null) != null;
+ bool b2 = loc4.Foreigns.Find(fk => fk.Columns.Find(c3 => c3.Name == c2.Name) != null) != null;
+ compare = b2.CompareTo(b1);
+ }
+ if (compare == 0) compare = c1.Name.CompareTo(c2.Name);
+ return compare;
+ });
+ loc1.Add(loc4);
+ }
+ loc1.Sort((t1, t2) => {
+ var ret = t1.Schema.CompareTo(t2.Schema);
+ if (ret == 0) ret = t1.Name.CompareTo(t2.Name);
+ return ret;
});
- loc1.Add(loc4);
- }
- loc1.Sort((t1, t2) => {
- var ret = t1.Schema.CompareTo(t2.Schema);
- if (ret == 0) ret = t1.Name.CompareTo(t2.Name);
- return ret;
- });
- foreach (var loc4 in loc1) {
- var dicUniques = new Dictionary>();
- dicUniques.Add(string.Join(",", loc4.Primarys.Select(a => a.Name)), loc4.Primarys);
- foreach (var loc5 in loc4.Uniques) {
- var dickey = string.Join(",", loc5.Select(a => a.Name));
- if (dicUniques.ContainsKey(dickey)) continue;
- dicUniques.Add(dickey, loc5);
+ foreach (var loc4 in loc1) {
+ var dicUniques = new Dictionary>();
+ if (loc4.Primarys.Count > 0) dicUniques.Add(string.Join(",", loc4.Primarys.Select(a => a.Name)), loc4.Primarys);
+ foreach (var loc5 in loc4.Uniques) {
+ var dickey = string.Join(",", loc5.Select(a => a.Name));
+ if (dicUniques.ContainsKey(dickey)) continue;
+ dicUniques.Add(dickey, loc5);
+ }
+ loc4.Uniques = dicUniques.Values.ToList();
}
- loc4.Uniques = dicUniques.Values.ToList();
- }
- loc2.Clear();
- loc3.Clear();
- return loc1;
+ loc2.Clear();
+ loc3.Clear();
+ tables.AddRange(loc1);
+ }
+ return tables;
}
}
}
\ No newline at end of file
diff --git a/Templates/MySql/rich-entity-navigation-object/Models/for-table.cs.freesql b/Templates/MySql/rich-entity-navigation-object/Model/for-table.cs.freesql
similarity index 85%
rename from Templates/MySql/rich-entity-navigation-object/Models/for-table.cs.freesql
rename to Templates/MySql/rich-entity-navigation-object/Model/for-table.cs.freesql
index a33178b3..41b88c1f 100644
--- a/Templates/MySql/rich-entity-navigation-object/Models/for-table.cs.freesql
+++ b/Templates/MySql/rich-entity-navigation-object/Model/for-table.cs.freesql
@@ -57,8 +57,8 @@ namespace test.Model {
{/if}{/for}{for fk in fks}
public {#UString(fk.ReferencedTable.Name)} {#GetFkObjectName(fk)} { get; set; }
{/for}
- internal static IFreeSql mysql => Const.mysql;
- public static ISelect<{#UString(table.Name)}> Select => mysql.Select<{#UString(table.Name)}>();
+ internal static IFreeSql freesql => Const.mysql;
+ public static ISelect<{#UString(table.Name)}> Select => freesql.Select<{#UString(table.Name)}>();
{if (table.Uniques.Count > 0)}
public static int ItemCacheTimeout = 180;{for uk001 in table.Uniques}{%
@@ -79,7 +79,7 @@ namespace test.Model {
parmsNodeTypeUpdateCacheRemove = parmsNodeTypeUpdateCacheRemove.Substring(0, parmsNodeTypeUpdateCacheRemove.Length - 9);
%}
public static {#UString(table.Name)} GetItem{#uk001[0].IsPrimary ? string.Empty : parmsBy}({#parms}) => Select.Where(a => {#parmsByWhereLambda}).Caching(ItemCacheTimeout, string.Concat("test:{#table.Name}{#uk001[0].IsPrimary ? string.Empty : parmsBy}:", {#parmsNodeTypeUpdateCacheRemove.Replace("item.", "")})).ToOne();{/for}
-{/if}{if (table.Uniques.Count > 0)}{for uk001 in table.Uniques}{%
+{for uk001 in table.Uniques}{%
string parms = string.Empty;
string parmsByWhereLambda = string.Empty;
@@ -101,12 +101,12 @@ namespace test.Model {
parmsNoneType = parmsNoneType.Substring(0, parmsNoneType.Length - 2);
%}
public static long Delete{#uk001[0].IsPrimary ? string.Empty : parmsBy}({#parms}) {
- var affrows = mysql.Delete<{#UString(table.Name)}>().Where(a => {#parmsByWhereLambda}).ExecuteAffrows();{if table.Uniques.Count > 1}
+ var affrows = freesql.Delete<{#UString(table.Name)}>().Where(a => {#parmsByWhereLambda}).ExecuteAffrows();{if table.Uniques.Count > 1}
if (ItemCacheTimeout > 0) RemoveCache(GetItem{#uk001[0].IsPrimary ? string.Empty : parmsBy}({#parmsNoneType}));{else}
if (ItemCacheTimeout > 0) RemoveCache(new {#UString(table.Name)} { {#parmsNewItem} });{/if}
return affrows;
}{/for}
-{/if}{for fkcoldel in fks}{%
+{for fkcoldel in fks}{%
string parms = string.Empty;
string parmsBy = "By";
string parmsByWhereLambda = string.Empty;
@@ -121,9 +121,9 @@ namespace test.Model {
parmsByWhereLambda = parmsByWhereLambda.Substring(0, parmsByWhereLambda.Length - 4);
%}
public static long DeleteBy{#parmsBy}({#parms}) {
- return mysql.Delete<{#UString(table.Name)}>().Where(a => {#parmsByWhereLambda}).ExecuteAffrows(); //删除缓存
+ return freesql.Delete<{#UString(table.Name)}>().Where(a => {#parmsByWhereLambda}).ExecuteAffrows(); //删除缓存
}
-{/for}{if (table.Uniques.Count > 0)}{% string redisRemoveCode = string.Empty; %}{for uk001 in table.Uniques}{%
+{/for}{% string redisRemoveCode = string.Empty; %}{for uk001 in table.Uniques}{%
string parmsBy = "By";
string parmsNodeTypeUpdateCacheRemove = string.Empty;
@@ -143,10 +143,10 @@ namespace test.Model {
var keysIdx = 0;
foreach (var item in items) {{#redisRemoveCode}
}
- if (mysql.Ado.TransactionCurrentThread != null) mysql.Ado.TransactionPreRemoveCache(keys);
- else mysql.Cache.Remove(keys);
+ if (freesql.Ado.TransactionCurrentThread != null) freesql.Ado.TransactionPreRemoveCache(keys);
+ else freesql.Cache.Remove(keys);
}
-{/if}{if (table.Columns.Count < 100)}{%
+{if (table.Columns.Count < 100)}{%
string CsParam3 = string.Empty;
string CsParamNoType3 = string.Empty;
string parms = string.Empty;
@@ -186,55 +186,55 @@ namespace test.Model {
if (CsParamNoType3.Length > 0) CsParamNoType3 = CsParamNoType3.Substring(0, CsParamNoType3.Length - 2);
%}{if idens > 0}
public static {#GetCsType(idensCol)} Insert({#UString(table.Name)} item) {
- item.{#UString(idensCol.Name)} = ({#GetCsType(idensCol)})mysql.Insert<{#UString(table.Name)}>().AppendData(item).ExecuteIdentity();
+ item.{#UString(idensCol.Name)} = ({#GetCsType(idensCol)})freesql.Insert<{#UString(table.Name)}>().AppendData(item).ExecuteIdentity();
if (ItemCacheTimeout > 0) RemoveCache(item);
return item.{#UString(idensCol.Name)};
}{else}
public static void Insert({#UString(table.Name)} item) {
if (ItemCacheTimeout > 0) RemoveCache(item);
- mysql.Insert<{#UString(table.Name)}>().AppendData(item).ExecuteAffrows();
+ freesql.Insert<{#UString(table.Name)}>().AppendData(item).ExecuteAffrows();
}
public static long Insert(IEnumerable<{#UString(table.Name)}> items) {
if (ItemCacheTimeout > 0) RemoveCache(items);
- return mysql.Insert<{#UString(table.Name)}>().AppendData(items).ExecuteAffrows();
+ return freesql.Insert<{#UString(table.Name)}>().AppendData(items).ExecuteAffrows();
}{/if}
{if CsParamNoType3.Split('=').Length <= 5}{if idens > 0}
public static {#GetCsType(idensCol)} Insert({#CsParam3}) {
var item = new {#UString(table.Name)} {{#CsParamNoType3}};
- item.{#UString(idensCol.Name)} = ({#GetCsType(idensCol)})mysql.Insert<{#UString(table.Name)}>().AppendData(new {#UString(table.Name)} {{#CsParamNoType3}}).ExecuteIdentity();
+ item.{#UString(idensCol.Name)} = ({#GetCsType(idensCol)})freesql.Insert<{#UString(table.Name)}>().AppendData(new {#UString(table.Name)} {{#CsParamNoType3}}).ExecuteIdentity();
if (ItemCacheTimeout > 0) RemoveCache(item);
return item.{#UString(idensCol.Name)};
}{else}
public static {#UString(table.Name)} Insert({#CsParam3}) {
var item = new {#UString(table.Name)} {{#CsParamNoType3}};
- mysql.Insert<{#UString(table.Name)}>().AppendData(item).ExecuteAffrows();
+ freesql.Insert<{#UString(table.Name)}>().AppendData(item).ExecuteAffrows();
if (ItemCacheTimeout > 0) RemoveCache(item);
return item;
}{/if}{/if}
public static long Update({#UString(table.Name)} item) {
if (ItemCacheTimeout > 0) RemoveCache(item);
- return mysql.Update<{#UString(table.Name)}>().SetSource(item).ExecuteAffrows();
+ return freesql.Update<{#UString(table.Name)}>().SetSource(item).ExecuteAffrows();
}
public static long Update(IEnumerable<{#UString(table.Name)}> items) {
if (ItemCacheTimeout > 0) RemoveCache(items);
- return mysql.Update<{#UString(table.Name)}>().SetSource(items).ExecuteAffrows();
+ return freesql.Update<{#UString(table.Name)}>().SetSource(items).ExecuteAffrows();
}
///
/// 指定字段更新
///
- public IUpdate<{#UString(table.Name)}> UpdateDiy => mysql.Update<{#UString(table.Name)}>().Where(a => {#parmsByWhereLambda});
+ public IUpdate<{#UString(table.Name)}> UpdateDiy => freesql.Update<{#UString(table.Name)}>().Where(a => {#parmsByWhereLambda});
///
/// {if pks.Count > 0}保存或添加,如果主键有值则尝试 Update,如果影响的行为 0 则尝试 Insert{else}添加{/if}
///
public void Save() {{if pks.Count > 0}
if ({#string.Join(" && ", pks.Select(pkssa => "this." + UString(pkssa.Name) + " != default(" + GetCsType(pkssa) + ")"))}) {
- var affrows = mysql.Update<{#UString(table.Name)}>().Where(a => {#parmsByWhereLambda}).ExecuteAffrows();
+ var affrows = freesql.Update<{#UString(table.Name)}>().Where(a => {#parmsByWhereLambda}).ExecuteAffrows();
if (affrows > 0) return;
}{/if}
- {if idens > 0}this.{#UString(idensCol.Name)} = {#GetCsType(idensCol).Replace("?", "") == "long" ? "" : ("(" + GetCsType(idensCol) + ")")}mysql.Insert<{#UString(table.Name)}>().AppendData(this).ExecuteIdentity();{else}
- mysql.Insert<{#UString(table.Name)}>().AppendData(this).ExecuteAffrows();{/if}
+ {if idens > 0}this.{#UString(idensCol.Name)} = {#GetCsType(idensCol).Replace("?", "") == "long" ? "" : ("(" + GetCsType(idensCol) + ")")}freesql.Insert<{#UString(table.Name)}>().AppendData(this).ExecuteIdentity();{else}
+ freesql.Insert<{#UString(table.Name)}>().AppendData(this).ExecuteAffrows();{/if}
}
-{/if}
+{/if}{/if}
}
{include ../../include/enumtype.tpl}
}
\ No newline at end of file
diff --git a/Templates/MySql/rich-entity-navigation-object/readme.md b/Templates/MySql/rich-entity-navigation-object/readme.md
index e69de29b..c95c10a5 100644
--- a/Templates/MySql/rich-entity-navigation-object/readme.md
+++ b/Templates/MySql/rich-entity-navigation-object/readme.md
@@ -0,0 +1,94 @@
+# 生成器
+
+生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板:
+
+| 模板名称 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 |
+| ------------- | - | - |- | - |- | - |
+| simple-entity | √ | X | X | √ | X | X |
+| simple-entity-navigation-object | √ | √ | X | √ | X | X |
+| rich-entity-navigation-object | √ | √ | √ | X | √ | X |
+
+模板在项目目录:/Templates/MySql
+
+> 更多模板逐步开发中。。。
+
+```csharp
+//定义 mysql FreeSql
+var mysql = new FreeSql.FreeSqlBuilder()
+ .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10")
+ .Build();
+
+//创建模板生成类现实
+var gen = new FreeSql.Generator.TemplateGenerator();
+gen.Build(mysql.DbFirst,
+ @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载)
+ @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录
+ "cccddd" //数据库
+);
+```
+
+## 模板语法
+
+```html
+
+
+{#title}
+
+
+
+
+{#表达式}
+{##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高
+
+
+{include ../header.html}
+
+
aaa
+
bbb {#i}
+
ccc {#i}
+
+
+
+{module module_name1 parms1, 2, 3...}
+{/module}
+{module module_name2 parms1, 2, 3...}
+{/module}
+
+
+{import ../module.html as myname}
+{#myname.module_name(parms1, 2, 3...)}
+
+
+{extends ../inc/layout.html}
+{block body}{/block}
+
+
+{%
+for (var a = 0; a < 100; a++)
+ print(a);
+%}
+
+
+{if i === 50}
+{elseif i > 60}
+{else}
+{/if}
+
+
+{for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2}
+
+{for item,index in items} 可选参数称 index
+ 可自定义名 {for item2, index99 in 数组表达式}
+
+{for key,item,index on json} 可选参数 item, index,
+ 可自定义名 {for key2, item2, index99 in 对象表达式}
+{/for}
+
+
+{miss}
+此块内容不被bmw.js解析
+{/miss}
+
+
+
+```
\ No newline at end of file
diff --git a/Templates/MySql/simple-entity-navigation-object/Models/for-table.cs.freesql b/Templates/MySql/simple-entity-navigation-object/Model/for-table.cs.freesql
similarity index 100%
rename from Templates/MySql/simple-entity-navigation-object/Models/for-table.cs.freesql
rename to Templates/MySql/simple-entity-navigation-object/Model/for-table.cs.freesql
diff --git a/Templates/MySql/simple-entity-navigation-object/readme.md b/Templates/MySql/simple-entity-navigation-object/readme.md
index e69de29b..c95c10a5 100644
--- a/Templates/MySql/simple-entity-navigation-object/readme.md
+++ b/Templates/MySql/simple-entity-navigation-object/readme.md
@@ -0,0 +1,94 @@
+# 生成器
+
+生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板:
+
+| 模板名称 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 |
+| ------------- | - | - |- | - |- | - |
+| simple-entity | √ | X | X | √ | X | X |
+| simple-entity-navigation-object | √ | √ | X | √ | X | X |
+| rich-entity-navigation-object | √ | √ | √ | X | √ | X |
+
+模板在项目目录:/Templates/MySql
+
+> 更多模板逐步开发中。。。
+
+```csharp
+//定义 mysql FreeSql
+var mysql = new FreeSql.FreeSqlBuilder()
+ .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10")
+ .Build();
+
+//创建模板生成类现实
+var gen = new FreeSql.Generator.TemplateGenerator();
+gen.Build(mysql.DbFirst,
+ @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载)
+ @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录
+ "cccddd" //数据库
+);
+```
+
+## 模板语法
+
+```html
+
+
+{#title}
+
+
+
+
+{#表达式}
+{##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高
+
+
+{include ../header.html}
+
+
aaa
+
bbb {#i}
+
ccc {#i}
+
+
+
+{module module_name1 parms1, 2, 3...}
+{/module}
+{module module_name2 parms1, 2, 3...}
+{/module}
+
+
+{import ../module.html as myname}
+{#myname.module_name(parms1, 2, 3...)}
+
+
+{extends ../inc/layout.html}
+{block body}{/block}
+
+
+{%
+for (var a = 0; a < 100; a++)
+ print(a);
+%}
+
+
+{if i === 50}
+{elseif i > 60}
+{else}
+{/if}
+
+
+{for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2}
+
+{for item,index in items} 可选参数称 index
+ 可自定义名 {for item2, index99 in 数组表达式}
+
+{for key,item,index on json} 可选参数 item, index,
+ 可自定义名 {for key2, item2, index99 in 对象表达式}
+{/for}
+
+
+{miss}
+此块内容不被bmw.js解析
+{/miss}
+
+
+
+```
\ No newline at end of file
diff --git a/Templates/MySql/simple-entity/Models/for-table.cs.freesql b/Templates/MySql/simple-entity/Model/for-table.cs.freesql
similarity index 100%
rename from Templates/MySql/simple-entity/Models/for-table.cs.freesql
rename to Templates/MySql/simple-entity/Model/for-table.cs.freesql
diff --git a/Templates/MySql/simple-entity/readme.md b/Templates/MySql/simple-entity/readme.md
index e69de29b..c95c10a5 100644
--- a/Templates/MySql/simple-entity/readme.md
+++ b/Templates/MySql/simple-entity/readme.md
@@ -0,0 +1,94 @@
+# 生成器
+
+生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板:
+
+| 模板名称 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 |
+| ------------- | - | - |- | - |- | - |
+| simple-entity | √ | X | X | √ | X | X |
+| simple-entity-navigation-object | √ | √ | X | √ | X | X |
+| rich-entity-navigation-object | √ | √ | √ | X | √ | X |
+
+模板在项目目录:/Templates/MySql
+
+> 更多模板逐步开发中。。。
+
+```csharp
+//定义 mysql FreeSql
+var mysql = new FreeSql.FreeSqlBuilder()
+ .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10")
+ .Build();
+
+//创建模板生成类现实
+var gen = new FreeSql.Generator.TemplateGenerator();
+gen.Build(mysql.DbFirst,
+ @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载)
+ @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录
+ "cccddd" //数据库
+);
+```
+
+## 模板语法
+
+```html
+
+
+{#title}
+
+
+
+
+{#表达式}
+{##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高
+
+
+{include ../header.html}
+
+
aaa
+
bbb {#i}
+
ccc {#i}
+
+
+
+{module module_name1 parms1, 2, 3...}
+{/module}
+{module module_name2 parms1, 2, 3...}
+{/module}
+
+
+{import ../module.html as myname}
+{#myname.module_name(parms1, 2, 3...)}
+
+
+{extends ../inc/layout.html}
+{block body}{/block}
+
+
+{%
+for (var a = 0; a < 100; a++)
+ print(a);
+%}
+
+
+{if i === 50}
+{elseif i > 60}
+{else}
+{/if}
+
+
+{for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2}
+
+{for item,index in items} 可选参数称 index
+ 可自定义名 {for item2, index99 in 数组表达式}
+
+{for key,item,index on json} 可选参数 item, index,
+ 可自定义名 {for key2, item2, index99 in 对象表达式}
+{/for}
+
+
+{miss}
+此块内容不被bmw.js解析
+{/miss}
+
+
+
+```
\ No newline at end of file
diff --git a/Templates/SqlServer/rich-entity-navigation-object/Const.cs b/Templates/SqlServer/rich-entity-navigation-object/Const.cs
new file mode 100644
index 00000000..783e7d9e
--- /dev/null
+++ b/Templates/SqlServer/rich-entity-navigation-object/Const.cs
@@ -0,0 +1,5 @@
+public static class Const {
+ public static IFreeSql sqlserver = new FreeSql.FreeSqlBuilder()
+ .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10")
+ .Build();
+}
diff --git a/Templates/SqlServer/rich-entity-navigation-object/Model/for-table.cs.freesql b/Templates/SqlServer/rich-entity-navigation-object/Model/for-table.cs.freesql
new file mode 100644
index 00000000..7a454552
--- /dev/null
+++ b/Templates/SqlServer/rich-entity-navigation-object/Model/for-table.cs.freesql
@@ -0,0 +1,240 @@
+{%if (table.Type == DbTableType.StoreProcedure) {
+ print("return;");
+ return rTn;
+ }
+ %}using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Reflection;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using FreeSql;
+using FreeSql.DataAnnotations;
+{%
+var dbf = dbfirst as FreeSql.IDbFirst;
+var cols = (table.Columns as List);
+var pks = (table.Primarys as List);
+var fks = (table.Foreigns as List);
+
+Func UString = stra => stra.Substring(0, 1).ToUpper() + stra.Substring(1);
+Func GetCsType = cola3 => {
+ return dbf.GetCsType(cola3);
+};
+Func GetFkObjectName = fkx => {
+ var eqfks = fks.Where(fk22a => fk22a.ReferencedTable.Name == fkx.ReferencedTable.Name);
+ if (eqfks.Count() == 1) return "Obj_" + fkx.ReferencedTable.Name;
+ var fkretname = fkx.Columns[0].Name;
+ if (fkretname.EndsWith(fkx.ReferencedColumns[0].Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(0, fkretname.Length - fkx.ReferencedColumns[0].Name.Length).TrimEnd('_');
+ if (fkretname.EndsWith(fkx.ReferencedTable.Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(0, fkretname.Length - fkx.ReferencedTable.Name.Length).TrimEnd('_');
+ if (fkretname.StartsWith(fkx.ReferencedTable.Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(fkx.ReferencedTable.Name.Length).TrimStart('_');
+ return "Obj_" + fkx.ReferencedTable.Name + (string.IsNullOrEmpty(fkretname) ? "" : ("_" + fkretname));
+};
+
+%}
+namespace test.Model {
+
+ [JsonObject(MemberSerialization.OptIn), Table(Name = "{#!string.IsNullOrEmpty(table.Schema) ? table.Schema + "." : ""}{#table.Name}"{if cols.Where(cola003 => cola003.Name.ToLower() == "is_deleted" || cola003.Name.ToLower() == "isdeleted").Any()}, SelectFilter = "a.IsDeleted = 1"{/if})]
+ public partial class {#UString(table.Name)} {{for col,index in table.Columns}{%
+ var findfks = fks.Where(fkaa => fkaa.Columns.Where(fkaac1 => fkaac1.Name == col.Name).Any());
+ %}{if findfks.Any() == false}
+ {if string.IsNullOrEmpty(col.Coment) == false}///
+ /// {#col.Coment.Replace("\r\n", "\n").Replace("\n", "\r\n /// ")}
+ /// {/if}
+ [JsonProperty, Column(Name = "{#col.Name}", DbType = "{#col.DbTypeTextFull}"{if col.IsPrimary == true}, IsPrimary = true{/if}{if col.IsIdentity == true}, IsIdentity = true{/if}{if col.IsNullable == true}, IsNullable = true{/if})]
+ public {#GetCsType(col)} {#UString(col.Name)} { get; set; }
+ {else}
+ private {#GetCsType(col)} _{#UString(col.Name)};
+ {if string.IsNullOrEmpty(col.Coment) == false}///
+ /// {#col.Coment.Replace("\r\n", "\n").Replace("\n", "\r\n /// ")}
+ /// {/if}
+ [JsonProperty, Column(Name = "{#col.Name}", DbType = "{#col.DbTypeTextFull}"{if col.IsPrimary == true}, IsPrimary = true{/if}{if col.IsIdentity == true}, IsIdentity = true{/if}{if col.IsNullable == true}, IsNullable = true{/if})]
+ public {#GetCsType(col)} {#UString(col.Name)} { get => _{#UString(col.Name)}; set {
+ if (_{#UString(col.Name)} == value) return;
+ _{#UString(col.Name)} = value;{for fkcok2 in findfks}
+ {#GetFkObjectName(fkcok2)} = null;{/for}
+ } }
+ {/if}{/for}{for fk in fks}
+ public {#UString(fk.ReferencedTable.Name)} {#GetFkObjectName(fk)} { get; set; }
+ {/for}
+ internal static IFreeSql freesql => Const.sqlserver;
+ public static ISelect<{#UString(table.Name)}> Select => freesql.Select<{#UString(table.Name)}>();
+{if (table.Uniques.Count > 0)}
+ public static int ItemCacheTimeout = 180;{for uk001 in table.Uniques}{%
+
+ string parms = string.Empty;
+ string parmsByWhereLambda = string.Empty;
+ string parmsBy = "By";
+ string parmsNodeTypeUpdateCacheRemove = string.Empty;
+ foreach (var uk001col in uk001) {
+ string getcstype = GetCsType(uk001col);
+ parms += getcstype.Replace("?", "") + " " + UString(uk001col.Name) + ", ";
+ parmsByWhereLambda += "a." + UString(uk001col.Name) + " == " + UString(uk001col.Name) + " && ";
+ parmsBy += UString(uk001col.Name) + "And";
+ parmsNodeTypeUpdateCacheRemove += "item." + UString(uk001col.Name) + ", \"_,_\", ";
+ }
+ parms = parms.Substring(0, parms.Length - 2);
+ parmsByWhereLambda = parmsByWhereLambda.Substring(0, parmsByWhereLambda.Length - 4);
+ parmsBy = parmsBy.Substring(0, parmsBy.Length - 3);
+ parmsNodeTypeUpdateCacheRemove = parmsNodeTypeUpdateCacheRemove.Substring(0, parmsNodeTypeUpdateCacheRemove.Length - 9);
+ %}
+ public static {#UString(table.Name)} GetItem{#uk001[0].IsPrimary ? string.Empty : parmsBy}({#parms}) => Select.Where(a => {#parmsByWhereLambda}).Caching(ItemCacheTimeout, string.Concat("test:{#table.Name}{#uk001[0].IsPrimary ? string.Empty : parmsBy}:", {#parmsNodeTypeUpdateCacheRemove.Replace("item.", "")})).ToOne();{/for}
+{for uk001 in table.Uniques}{%
+
+ string parms = string.Empty;
+ string parmsByWhereLambda = string.Empty;
+ string parmsNewItem = string.Empty;
+ string parmsBy = "By";
+ string parmsNoneType = string.Empty;
+ foreach (var uk001col in uk001) {
+ string getcstype = GetCsType(uk001col);
+ parms += getcstype.Replace("?", "") + " " + UString(uk001col.Name) + ", ";
+ parmsByWhereLambda += "a." + UString(uk001col.Name) + " == " + UString(uk001col.Name) + " && ";
+ parmsNewItem += UString(uk001col.Name) + " = " + UString(uk001col.Name) + ", ";
+ parmsBy += UString(uk001col.Name) + "And";
+ parmsNoneType += UString(uk001col.Name) + ", ";
+ }
+ parms = parms.Substring(0, parms.Length - 2);
+ parmsByWhereLambda = parmsByWhereLambda.Substring(0, parmsByWhereLambda.Length - 4);
+ parmsNewItem = parmsNewItem.Substring(0, parmsNewItem.Length - 2);
+ parmsBy = parmsBy.Substring(0, parmsBy.Length - 3);
+ parmsNoneType = parmsNoneType.Substring(0, parmsNoneType.Length - 2);
+ %}
+ public static long Delete{#uk001[0].IsPrimary ? string.Empty : parmsBy}({#parms}) {
+ var affrows = freesql.Delete<{#UString(table.Name)}>().Where(a => {#parmsByWhereLambda}).ExecuteAffrows();{if table.Uniques.Count > 1}
+ if (ItemCacheTimeout > 0) RemoveCache(GetItem{#uk001[0].IsPrimary ? string.Empty : parmsBy}({#parmsNoneType}));{else}
+ if (ItemCacheTimeout > 0) RemoveCache(new {#UString(table.Name)} { {#parmsNewItem} });{/if}
+ return affrows;
+ }{/for}
+{for fkcoldel in fks}{%
+ string parms = string.Empty;
+ string parmsBy = "By";
+ string parmsByWhereLambda = string.Empty;
+ foreach( var fkcoldelcol in fkcoldel.Columns) {
+ string getcstype = GetCsType(fkcoldelcol);
+ parms += getcstype.Replace("?", "") + " " + UString(fkcoldelcol.Name) + ", ";
+ parmsBy += UString(fkcoldelcol.Name) + "And";
+ parmsByWhereLambda += "a." + UString(fkcoldelcol.Name) + " == " + UString(fkcoldelcol.Name) + " && ";
+ }
+ parms = parms.Substring(0, parms.Length - 2);
+ parmsBy = parmsBy.Substring(0, parmsBy.Length - 3);
+ parmsByWhereLambda = parmsByWhereLambda.Substring(0, parmsByWhereLambda.Length - 4);
+ %}
+ public static long DeleteBy{#parmsBy}({#parms}) {
+ return freesql.Delete<{#UString(table.Name)}>().Where(a => {#parmsByWhereLambda}).ExecuteAffrows(); //删除缓存
+ }
+{/for}{% string redisRemoveCode = string.Empty; %}{for uk001 in table.Uniques}{%
+
+ string parmsBy = "By";
+ string parmsNodeTypeUpdateCacheRemove = string.Empty;
+ foreach (var uk001col in uk001) {
+ parmsBy += UString(uk001col.Name) + "And";
+ parmsNodeTypeUpdateCacheRemove += "item." + UString(uk001col.Name) + ", \"_,_\", ";
+ }
+ parmsBy = parmsBy.Substring(0, parmsBy.Length - 3);
+ parmsNodeTypeUpdateCacheRemove = parmsNodeTypeUpdateCacheRemove.Substring(0, parmsNodeTypeUpdateCacheRemove.Length - 9);
+ redisRemoveCode += $@"
+ keys[keysIdx++] = string.Concat(""test:{table.Name}{(uk001[0].IsPrimary ? string.Empty : parmsBy)}:"", {parmsNodeTypeUpdateCacheRemove});";
+ %}{/for}
+ internal static void RemoveCache({#UString(table.Name)} item) => RemoveCache(item == null ? null : new [] { item });
+ internal static void RemoveCache(IEnumerable<{#UString(table.Name)}> items) {
+ if (ItemCacheTimeout <= 0 || items == null || items.Any() == false) return;
+ var keys = new string[items.Count() * {#table.Uniques.Count}];
+ var keysIdx = 0;
+ foreach (var item in items) {{#redisRemoveCode}
+ }
+ if (freesql.Ado.TransactionCurrentThread != null) freesql.Ado.TransactionPreRemoveCache(keys);
+ else freesql.Cache.Remove(keys);
+ }
+{if (table.Columns.Count < 100)}{%
+ string CsParam3 = string.Empty;
+ string CsParamNoType3 = string.Empty;
+ string parms = string.Empty;
+ string parmsByWhereLambda = string.Empty;
+ string parmsNewItem = string.Empty;
+ string parmsBy = "By";
+ string parmsNoneType = string.Empty;
+ var idens = 0;
+ var idensCol = table.Columns[0];
+ foreach (var uk001col in table.Columns) {
+ string getcstype = GetCsType(uk001col);
+ parms += getcstype.Replace("?", "") + " " + UString(uk001col.Name) + ", ";
+ if (uk001col.IsPrimary)
+ parmsByWhereLambda += "a." + UString(uk001col.Name) + " == " + UString(uk001col.Name) + " && ";
+ parmsNewItem += UString(uk001col.Name) + " = " + UString(uk001col.Name) + ", ";
+ parmsBy += UString(uk001col.Name) + "And";
+ parmsNoneType += UString(uk001col.Name) + ", ";
+ if (uk001col.IsIdentity) {
+ idens++;
+ idensCol = uk001col;
+ } else {
+ if (getcstype.StartsWith("DateTime") && (uk001col.Name.ToLower() == "create_time" || uk001col.Name.ToLower() == "update_time" || uk001col.Name.ToLower() == "createtime" || uk001col.Name.ToLower() == "updatetime") ||
+ getcstype == "bool?" && (uk001col.Name.ToLower() == "is_deleted" || uk001col.Name.ToLower() == "isdeleted")) {
+
+ } else {
+ CsParam3 += getcstype + " " + UString(uk001col.Name) + ", ";
+ CsParamNoType3 += string.Format("\r\n {0} = {0}, ", UString(uk001col.Name));
+ }
+ }
+ }
+ parms = parms.Substring(0, parms.Length - 2);
+ if (parmsByWhereLambda.Length > 0) parmsByWhereLambda = parmsByWhereLambda.Substring(0, parmsByWhereLambda.Length - 4);
+ parmsNewItem = parmsNewItem.Substring(0, parmsNewItem.Length - 2);
+ parmsBy = parmsBy.Substring(0, parmsBy.Length - 3);
+ parmsNoneType = parmsNoneType.Substring(0, parmsNoneType.Length - 2);
+ if (CsParam3.Length > 0) CsParam3 = CsParam3.Substring(0, CsParam3.Length - 2);
+ if (CsParamNoType3.Length > 0) CsParamNoType3 = CsParamNoType3.Substring(0, CsParamNoType3.Length - 2);
+ %}{if idens > 0}
+ public static {#GetCsType(idensCol)} Insert({#UString(table.Name)} item) {
+ item.{#UString(idensCol.Name)} = ({#GetCsType(idensCol)})freesql.Insert<{#UString(table.Name)}>().AppendData(item).ExecuteIdentity();
+ if (ItemCacheTimeout > 0) RemoveCache(item);
+ return item.{#UString(idensCol.Name)};
+ }{else}
+ public static void Insert({#UString(table.Name)} item) {
+ if (ItemCacheTimeout > 0) RemoveCache(item);
+ freesql.Insert<{#UString(table.Name)}>().AppendData(item).ExecuteAffrows();
+ }
+ public static long Insert(IEnumerable<{#UString(table.Name)}> items) {
+ if (ItemCacheTimeout > 0) RemoveCache(items);
+ return freesql.Insert<{#UString(table.Name)}>().AppendData(items).ExecuteAffrows();
+ }{/if}
+ {if CsParamNoType3.Split('=').Length <= 5}{if idens > 0}
+ public static {#GetCsType(idensCol)} Insert({#CsParam3}) {
+ var item = new {#UString(table.Name)} {{#CsParamNoType3}};
+ item.{#UString(idensCol.Name)} = ({#GetCsType(idensCol)})freesql.Insert<{#UString(table.Name)}>().AppendData(new {#UString(table.Name)} {{#CsParamNoType3}}).ExecuteIdentity();
+ if (ItemCacheTimeout > 0) RemoveCache(item);
+ return item.{#UString(idensCol.Name)};
+ }{else}
+ public static {#UString(table.Name)} Insert({#CsParam3}) {
+ var item = new {#UString(table.Name)} {{#CsParamNoType3}};
+ freesql.Insert<{#UString(table.Name)}>().AppendData(item).ExecuteAffrows();
+ if (ItemCacheTimeout > 0) RemoveCache(item);
+ return item;
+ }{/if}{/if}
+ public static long Update({#UString(table.Name)} item) {
+ if (ItemCacheTimeout > 0) RemoveCache(item);
+ return freesql.Update<{#UString(table.Name)}>().SetSource(item).ExecuteAffrows();
+ }
+ public static long Update(IEnumerable<{#UString(table.Name)}> items) {
+ if (ItemCacheTimeout > 0) RemoveCache(items);
+ return freesql.Update<{#UString(table.Name)}>().SetSource(items).ExecuteAffrows();
+ }
+ ///
+ /// 指定字段更新
+ ///
+ public IUpdate<{#UString(table.Name)}> UpdateDiy => freesql.Update<{#UString(table.Name)}>().Where(a => {#parmsByWhereLambda});
+ ///
+ /// {if pks.Count > 0}保存或添加,如果主键有值则尝试 Update,如果影响的行为 0 则尝试 Insert{else}添加{/if}
+ ///
+ public void Save() {{if pks.Count > 0}
+ if ({#string.Join(" && ", pks.Select(pkssa => "this." + UString(pkssa.Name) + " != default(" + GetCsType(pkssa) + ")"))}) {
+ var affrows = freesql.Update<{#UString(table.Name)}>().Where(a => {#parmsByWhereLambda}).ExecuteAffrows();
+ if (affrows > 0) return;
+ }{/if}
+ {if idens > 0}this.{#UString(idensCol.Name)} = {#GetCsType(idensCol).Replace("?", "") == "long" ? "" : ("(" + GetCsType(idensCol) + ")")}freesql.Insert<{#UString(table.Name)}>().AppendData(this).ExecuteIdentity();{else}
+ freesql.Insert<{#UString(table.Name)}>().AppendData(this).ExecuteAffrows();{/if}
+ }
+{/if}{/if}
+ }
+}
\ No newline at end of file
diff --git a/Templates/SqlServer/rich-entity-navigation-object/readme.md b/Templates/SqlServer/rich-entity-navigation-object/readme.md
new file mode 100644
index 00000000..c95c10a5
--- /dev/null
+++ b/Templates/SqlServer/rich-entity-navigation-object/readme.md
@@ -0,0 +1,94 @@
+# 生成器
+
+生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板:
+
+| 模板名称 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 |
+| ------------- | - | - |- | - |- | - |
+| simple-entity | √ | X | X | √ | X | X |
+| simple-entity-navigation-object | √ | √ | X | √ | X | X |
+| rich-entity-navigation-object | √ | √ | √ | X | √ | X |
+
+模板在项目目录:/Templates/MySql
+
+> 更多模板逐步开发中。。。
+
+```csharp
+//定义 mysql FreeSql
+var mysql = new FreeSql.FreeSqlBuilder()
+ .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10")
+ .Build();
+
+//创建模板生成类现实
+var gen = new FreeSql.Generator.TemplateGenerator();
+gen.Build(mysql.DbFirst,
+ @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载)
+ @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录
+ "cccddd" //数据库
+);
+```
+
+## 模板语法
+
+```html
+
+
+{#title}
+
+
+
+
+{#表达式}
+{##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高
+
+
+{include ../header.html}
+
+
aaa
+
bbb {#i}
+
ccc {#i}
+
+
+
+{module module_name1 parms1, 2, 3...}
+{/module}
+{module module_name2 parms1, 2, 3...}
+{/module}
+
+
+{import ../module.html as myname}
+{#myname.module_name(parms1, 2, 3...)}
+
+
+{extends ../inc/layout.html}
+{block body}{/block}
+
+
+{%
+for (var a = 0; a < 100; a++)
+ print(a);
+%}
+
+
+{if i === 50}
+{elseif i > 60}
+{else}
+{/if}
+
+
+{for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2}
+
+{for item,index in items} 可选参数称 index
+ 可自定义名 {for item2, index99 in 数组表达式}
+
+{for key,item,index on json} 可选参数 item, index,
+ 可自定义名 {for key2, item2, index99 in 对象表达式}
+{/for}
+
+
+{miss}
+此块内容不被bmw.js解析
+{/miss}
+
+
+
+```
\ No newline at end of file
diff --git a/Templates/SqlServer/simple-entity-navigation-object/Model/for-table.cs.freesql b/Templates/SqlServer/simple-entity-navigation-object/Model/for-table.cs.freesql
new file mode 100644
index 00000000..3d606937
--- /dev/null
+++ b/Templates/SqlServer/simple-entity-navigation-object/Model/for-table.cs.freesql
@@ -0,0 +1,59 @@
+{%if (table.Type == DbTableType.StoreProcedure) {
+ print("return;");
+ return rTn;
+ }
+ %}using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using FreeSql.DataAnnotations;
+{%
+var dbf = dbfirst as FreeSql.IDbFirst;
+var cols = (table.Columns as List);
+var pks = (table.Primarys as List);
+var fks = (table.Foreigns as List);
+
+Func UString = stra => stra.Substring(0, 1).ToUpper() + stra.Substring(1);
+Func GetCsType = cola3 => {
+ return dbf.GetCsType(cola3);
+};
+Func GetFkObjectName = fkx => {
+ var eqfks = fks.Where(fk22a => fk22a.ReferencedTable.Name == fkx.ReferencedTable.Name);
+ if (eqfks.Count() == 1) return "Obj_" + fkx.ReferencedTable.Name;
+ var fkretname = fkx.Columns[0].Name;
+ if (fkretname.EndsWith(fkx.ReferencedColumns[0].Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(0, fkretname.Length - fkx.ReferencedColumns[0].Name.Length).TrimEnd('_');
+ if (fkretname.EndsWith(fkx.ReferencedTable.Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(0, fkretname.Length - fkx.ReferencedTable.Name.Length).TrimEnd('_');
+ if (fkretname.StartsWith(fkx.ReferencedTable.Name, StringComparison.CurrentCultureIgnoreCase)) fkretname = fkretname.Substring(fkx.ReferencedTable.Name.Length).TrimStart('_');
+ return "Obj_" + fkx.ReferencedTable.Name + (string.IsNullOrEmpty(fkretname) ? "" : ("_" + fkretname));
+};
+%}
+namespace test.Model {
+
+ [JsonObject(MemberSerialization.OptIn), Table(Name = "{#!string.IsNullOrEmpty(table.Schema) ? table.Schema + "." : ""}{#table.Name}"{if cols.Where(cola003 => cola003.Name.ToLower() == "is_deleted" || cola003.Name.ToLower() == "isdeleted").Any()}, SelectFilter = "a.IsDeleted = 1"{/if})]
+ public partial class {#UString(table.Name)} {{for col,index in table.Columns}{%
+ var findfks = fks.Where(fkaa => fkaa.Columns.Where(fkaac1 => fkaac1.Name == col.Name).Any());
+ %}{if findfks.Any() == false}
+ {if string.IsNullOrEmpty(col.Coment) == false}///
+ /// {#col.Coment.Replace("\r\n", "\n").Replace("\n", "\r\n /// ")}
+ /// {/if}
+ [JsonProperty, Column(Name = "{#col.Name}", DbType = "{#col.DbTypeTextFull}"{if col.IsPrimary == true}, IsPrimary = true{/if}{if col.IsIdentity == true}, IsIdentity = true{/if}{if col.IsNullable == true}, IsNullable = true{/if})]
+ public {#GetCsType(col)} {#UString(col.Name)} { get; set; }
+ {else}
+ private {#GetCsType(col)} _{#UString(col.Name)};
+ {if string.IsNullOrEmpty(col.Coment) == false}///
+ /// {#col.Coment.Replace("\r\n", "\n").Replace("\n", "\r\n /// ")}
+ /// {/if}
+ [JsonProperty, Column(Name = "{#col.Name}", DbType = "{#col.DbTypeTextFull}"{if col.IsPrimary == true}, IsPrimary = true{/if}{if col.IsIdentity == true}, IsIdentity = true{/if}{if col.IsNullable == true}, IsNullable = true{/if})]
+ public {#GetCsType(col)} {#UString(col.Name)} { get => _{#UString(col.Name)}; set {
+ if (_{#UString(col.Name)} == value) return;
+ _{#UString(col.Name)} = value;{for fkcok2 in findfks}
+ {#GetFkObjectName(fkcok2)} = null;{/for}
+ } }
+ {/if}{/for}{for fk in fks}
+ public {#UString(fk.ReferencedTable.Name)} {#GetFkObjectName(fk)} { get; set; }
+ {/for}
+ }
+}
\ No newline at end of file
diff --git a/Templates/SqlServer/simple-entity-navigation-object/readme.md b/Templates/SqlServer/simple-entity-navigation-object/readme.md
new file mode 100644
index 00000000..c95c10a5
--- /dev/null
+++ b/Templates/SqlServer/simple-entity-navigation-object/readme.md
@@ -0,0 +1,94 @@
+# 生成器
+
+生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板:
+
+| 模板名称 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 |
+| ------------- | - | - |- | - |- | - |
+| simple-entity | √ | X | X | √ | X | X |
+| simple-entity-navigation-object | √ | √ | X | √ | X | X |
+| rich-entity-navigation-object | √ | √ | √ | X | √ | X |
+
+模板在项目目录:/Templates/MySql
+
+> 更多模板逐步开发中。。。
+
+```csharp
+//定义 mysql FreeSql
+var mysql = new FreeSql.FreeSqlBuilder()
+ .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10")
+ .Build();
+
+//创建模板生成类现实
+var gen = new FreeSql.Generator.TemplateGenerator();
+gen.Build(mysql.DbFirst,
+ @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载)
+ @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录
+ "cccddd" //数据库
+);
+```
+
+## 模板语法
+
+```html
+
+
+{#title}
+
+
+
+
+{#表达式}
+{##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高
+
+
+{include ../header.html}
+
+
aaa
+
bbb {#i}
+
ccc {#i}
+
+
+
+{module module_name1 parms1, 2, 3...}
+{/module}
+{module module_name2 parms1, 2, 3...}
+{/module}
+
+
+{import ../module.html as myname}
+{#myname.module_name(parms1, 2, 3...)}
+
+
+{extends ../inc/layout.html}
+{block body}{/block}
+
+
+{%
+for (var a = 0; a < 100; a++)
+ print(a);
+%}
+
+
+{if i === 50}
+{elseif i > 60}
+{else}
+{/if}
+
+
+{for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2}
+
+{for item,index in items} 可选参数称 index
+ 可自定义名 {for item2, index99 in 数组表达式}
+
+{for key,item,index on json} 可选参数 item, index,
+ 可自定义名 {for key2, item2, index99 in 对象表达式}
+{/for}
+
+
+{miss}
+此块内容不被bmw.js解析
+{/miss}
+
+
+
+```
\ No newline at end of file
diff --git a/Templates/SqlServer/simple-entity/Model/for-table.cs.freesql b/Templates/SqlServer/simple-entity/Model/for-table.cs.freesql
new file mode 100644
index 00000000..86f7cb7f
--- /dev/null
+++ b/Templates/SqlServer/simple-entity/Model/for-table.cs.freesql
@@ -0,0 +1,33 @@
+{%if (table.Type == DbTableType.StoreProcedure) {
+ print("return;");
+ return rTn;
+ }
+ %}using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using FreeSql.DataAnnotations;
+{%
+var dbf = dbfirst as FreeSql.IDbFirst;
+var cols = (table.Columns as List);
+
+Func UString = stra => stra.Substring(0, 1).ToUpper() + stra.Substring(1);
+Func GetCsType = cola3 => {
+ return dbf.GetCsType(cola3);
+};
+%}
+namespace test.Model {
+
+ [JsonObject(MemberSerialization.OptIn), Table(Name = "{#!string.IsNullOrEmpty(table.Schema) ? table.Schema + "." : ""}{#table.Name}"{if cols.Where(cola003 => cola003.Name.ToLower() == "is_deleted" || cola003.Name.ToLower() == "isdeleted").Any()}, SelectFilter = "a.IsDeleted = 1"{/if})]
+ public partial class {#UString(table.Name)} {{for col,index in table.Columns}
+ {if string.IsNullOrEmpty(col.Coment) == false}///
+ /// {#col.Coment.Replace("\r\n", "\n").Replace("\n", "\r\n /// ")}
+ /// {/if}
+ [JsonProperty, Column(Name = "{#col.Name}", DbType = "{#col.DbTypeTextFull}"{if col.IsPrimary == true}, IsPrimary = true{/if}{if col.IsIdentity == true}, IsIdentity = true{/if}{if col.IsNullable == true}, IsNullable = true{/if})]
+ public {#GetCsType(col)} {#UString(col.Name)} { get; set; }
+ {/for}
+ }
+}
\ No newline at end of file
diff --git a/Templates/SqlServer/simple-entity/readme.md b/Templates/SqlServer/simple-entity/readme.md
new file mode 100644
index 00000000..c95c10a5
--- /dev/null
+++ b/Templates/SqlServer/simple-entity/readme.md
@@ -0,0 +1,94 @@
+# 生成器
+
+生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板:
+
+| 模板名称 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 |
+| ------------- | - | - |- | - |- | - |
+| simple-entity | √ | X | X | √ | X | X |
+| simple-entity-navigation-object | √ | √ | X | √ | X | X |
+| rich-entity-navigation-object | √ | √ | √ | X | √ | X |
+
+模板在项目目录:/Templates/MySql
+
+> 更多模板逐步开发中。。。
+
+```csharp
+//定义 mysql FreeSql
+var mysql = new FreeSql.FreeSqlBuilder()
+ .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10")
+ .Build();
+
+//创建模板生成类现实
+var gen = new FreeSql.Generator.TemplateGenerator();
+gen.Build(mysql.DbFirst,
+ @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载)
+ @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录
+ "cccddd" //数据库
+);
+```
+
+## 模板语法
+
+```html
+
+
+{#title}
+
+
+
+
+{#表达式}
+{##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高
+
+
+{include ../header.html}
+
+
aaa
+
bbb {#i}
+
ccc {#i}
+
+
+
+{module module_name1 parms1, 2, 3...}
+{/module}
+{module module_name2 parms1, 2, 3...}
+{/module}
+
+
+{import ../module.html as myname}
+{#myname.module_name(parms1, 2, 3...)}
+
+
+{extends ../inc/layout.html}
+{block body}{/block}
+
+
+{%
+for (var a = 0; a < 100; a++)
+ print(a);
+%}
+
+
+{if i === 50}
+{elseif i > 60}
+{else}
+{/if}
+
+
+{for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2}
+
+{for item,index in items} 可选参数称 index
+ 可自定义名 {for item2, index99 in 数组表达式}
+
+{for key,item,index on json} 可选参数 item, index,
+ 可自定义名 {for key2, item2, index99 in 对象表达式}
+{/for}
+
+
+{miss}
+此块内容不被bmw.js解析
+{/miss}
+
+
+
+```
\ No newline at end of file
From 4e45bb184e2a8f2f606ee67743715e2b121dca4b Mon Sep 17 00:00:00 2001
From: 28810 <28810@YEXIANGQIN>
Date: Wed, 19 Dec 2018 17:06:38 +0800
Subject: [PATCH 4/6] =?UTF-8?q?SqlServer=20=E5=8D=95=E5=85=83=E6=B5=8B?=
=?UTF-8?q?=E8=AF=95=20Curd=20=E8=B5=B0=E9=80=9A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs | 10 +-
.../SqlServer/Curd/SqlServerDeleteTest.cs | 73 +++
.../SqlServer/Curd/SqlServerInsertTest.cs | 85 +++
.../SqlServer/Curd/SqlServerSelectTest.cs | 501 ++++++++++++++++++
.../SqlServer/Curd/SqlServerUpdateTest.cs | 107 ++++
.../SqlServerAdo/SqlServerAdoTest.cs | 55 ++
FreeSql.Tests/g.cs | 2 +-
FreeSql/Interface/IAdo.cs | 20 +-
FreeSql/Internal/CommonExpression.cs | 25 +-
.../Internal/CommonProvider/InsertProvider.cs | 2 +-
.../Internal/CommonProvider/UpdateProvider.cs | 4 +-
FreeSql/MySql/Curd/MySqlDelete.cs | 3 +-
FreeSql/MySql/Curd/MySqlInsert.cs | 2 +-
FreeSql/MySql/Curd/MySqlUpdate.cs | 20 +-
FreeSql/PostgreSQL/Curd/PostgreSQLDelete.cs | 3 +-
FreeSql/PostgreSQL/Curd/PostgreSQLInsert.cs | 2 +-
FreeSql/PostgreSQL/Curd/PostgreSQLUpdate.cs | 24 +-
FreeSql/SqlServer/Curd/SqlServerDelete.cs | 3 +-
FreeSql/SqlServer/Curd/SqlServerInsert.cs | 4 +-
FreeSql/SqlServer/Curd/SqlServerUpdate.cs | 18 +-
FreeSql/SqlServer/SqlServerCodeFirst.cs | 12 +-
21 files changed, 933 insertions(+), 42 deletions(-)
create mode 100644 FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs
create mode 100644 FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs
create mode 100644 FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs
create mode 100644 FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs
create mode 100644 FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs
diff --git a/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs
index 5e2f3e84..bbc0e659 100644
--- a/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs
+++ b/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs
@@ -343,9 +343,9 @@ namespace FreeSql.Tests.MySql {
query2.ToList();
//������϶����㲻��
- query = select.Where("a.clicks > 100 && a.id = ?id", new { id = 10 });
+ query = select.Where("a.clicks > 100 and a.id = ?id", new { id = 10 });
sql = query.ToSql().Replace("\r\n", "");
- Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a WHERE (a.clicks > 100 && a.id = ?id)", sql);
+ Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a WHERE (a.clicks > 100 and a.id = ?id)", sql);
query.ToList();
}
[Fact]
@@ -390,9 +390,9 @@ namespace FreeSql.Tests.MySql {
query2.ToList();
//������϶����㲻��
- query = select.WhereIf(true, "a.clicks > 100 && a.id = ?id", new { id = 10 });
+ query = select.WhereIf(true, "a.clicks > 100 and a.id = ?id", new { id = 10 });
sql = query.ToSql().Replace("\r\n", "");
- Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a WHERE (a.clicks > 100 && a.id = ?id)", sql);
+ Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a WHERE (a.clicks > 100 and a.id = ?id)", sql);
query.ToList();
// ==========================================WhereIf(false)
@@ -437,7 +437,7 @@ namespace FreeSql.Tests.MySql {
query2.ToList();
//������϶����㲻��
- query = select.WhereIf(false, "a.clicks > 100 && a.id = ?id", new { id = 10 });
+ query = select.WhereIf(false, "a.clicks > 100 and a.id = ?id", new { id = 10 });
sql = query.ToSql().Replace("\r\n", "");
Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a", sql);
query.ToList();
diff --git a/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs b/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs
new file mode 100644
index 00000000..86b79b56
--- /dev/null
+++ b/FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs
@@ -0,0 +1,73 @@
+using FreeSql.DataAnnotations;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace FreeSql.Tests.SqlServer {
+ public class SqlServerDeleteTest {
+
+ IDelete delete => g.sqlserver.Delete(); //��������
+
+ [Table(Name = "tb_topic")]
+ class Topic {
+ [Column(IsIdentity = true, IsPrimary = true)]
+ public int Id { get; set; }
+ public int Clicks { get; set; }
+ public TestTypeInfo Type { get; set; }
+ public string Title { get; set; }
+ public DateTime CreateTime { get; set; }
+ }
+
+ [Fact]
+ public void Dywhere() {
+ Assert.Null(g.sqlserver.Delete().ToSql());
+ var sql = g.sqlserver.Delete(new[] { 1, 2 }).ToSql();
+ Assert.Equal("DELETE FROM [tb_topic] WHERE ([Id] = 1 OR [Id] = 2)", sql);
+
+ sql = g.sqlserver.Delete(new Topic { Id = 1, Title = "test" }).ToSql();
+ Assert.Equal("DELETE FROM [tb_topic] WHERE ([Id] = 1)", sql);
+
+ sql = g.sqlserver.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql();
+ Assert.Equal("DELETE FROM [tb_topic] WHERE ([Id] = 1 OR [Id] = 2)", sql);
+
+ sql = g.sqlserver.Delete(new { id = 1 }).ToSql();
+ Assert.Equal("DELETE FROM [tb_topic] WHERE ([Id] = 1)", sql);
+ }
+
+ [Fact]
+ public void Where() {
+ var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", "");
+ Assert.Equal("DELETE FROM [tb_topic] WHERE ([Id] = 1)", sql);
+
+ sql = delete.Where("id = ?id", new { id = 1 }).ToSql().Replace("\r\n", "");
+ Assert.Equal("DELETE FROM [tb_topic] WHERE (id = ?id)", sql);
+
+ var item = new Topic { Id = 1, Title = "newtitle" };
+ sql = delete.Where(item).ToSql().Replace("\r\n", "");
+ Assert.Equal("DELETE FROM [tb_topic] WHERE ([Id] = 1)", sql);
+
+ var items = new List();
+ for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 });
+
+ sql = delete.Where(items).ToSql().Replace("\r\n", "");
+ Assert.Equal("DELETE FROM [tb_topic] WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql);
+ }
+ [Fact]
+ public void WhereExists() {
+
+ }
+ [Fact]
+ public void ExecuteAffrows() {
+
+ var id = g.sqlserver.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity();
+ Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows());
+ }
+ [Fact]
+ public void ExecuteDeleted() {
+
+ var item = g.sqlserver.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted();
+ Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id);
+ }
+ }
+}
diff --git a/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs b/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs
new file mode 100644
index 00000000..b60fe033
--- /dev/null
+++ b/FreeSql.Tests/SqlServer/Curd/SqlServerInsertTest.cs
@@ -0,0 +1,85 @@
+using FreeSql.DataAnnotations;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace FreeSql.Tests.SqlServer {
+ public class SqlServerInsertTest {
+
+ IInsert insert => g.sqlserver.Insert(); //��������
+
+ [Table(Name = "tb_topic")]
+ class Topic {
+ [Column(IsIdentity = true, IsPrimary = true)]
+ public int Id { get; set; }
+ public int Clicks { get; set; }
+ public TestTypeInfo Type { get; set; }
+ public string Title { get; set; }
+ public DateTime CreateTime { get; set; }
+ }
+
+ [Fact]
+ public void AppendData() {
+ var items = new List();
+ for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now });
+
+ var sql = insert.AppendData(items.First()).ToSql();
+ Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(@Clicks0, @Title0, @CreateTime0)", sql);
+
+ sql = insert.AppendData(items).ToSql();
+ Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(@Clicks0, @Title0, @CreateTime0), (@Clicks1, @Title1, @CreateTime1), (@Clicks2, @Title2, @CreateTime2), (@Clicks3, @Title3, @CreateTime3), (@Clicks4, @Title4, @CreateTime4), (@Clicks5, @Title5, @CreateTime5), (@Clicks6, @Title6, @CreateTime6), (@Clicks7, @Title7, @CreateTime7), (@Clicks8, @Title8, @CreateTime8), (@Clicks9, @Title9, @CreateTime9)", sql);
+
+ sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql();
+ Assert.Equal("INSERT INTO [tb_topic]([Title]) VALUES(@Title0), (@Title1), (@Title2), (@Title3), (@Title4), (@Title5), (@Title6), (@Title7), (@Title8), (@Title9)", sql);
+
+ sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql();
+ Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql);
+ }
+
+ [Fact]
+ public void InsertColumns() {
+ var items = new List();
+ for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now });
+
+ var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql();
+ Assert.Equal("INSERT INTO [tb_topic]([Title]) VALUES(@Title0), (@Title1), (@Title2), (@Title3), (@Title4), (@Title5), (@Title6), (@Title7), (@Title8), (@Title9)", sql);
+
+ sql = insert.AppendData(items).InsertColumns(a =>new { a.Title, a.Clicks }).ToSql();
+ Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql);
+ }
+ [Fact]
+ public void IgnoreColumns() {
+ var items = new List();
+ for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now });
+
+ var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql();
+ Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(@Clicks0, @Title0), (@Clicks1, @Title1), (@Clicks2, @Title2), (@Clicks3, @Title3), (@Clicks4, @Title4), (@Clicks5, @Title5), (@Clicks6, @Title6), (@Clicks7, @Title7), (@Clicks8, @Title8), (@Clicks9, @Title9)", sql);
+
+ sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql();
+ Assert.Equal("INSERT INTO [tb_topic]([Clicks]) VALUES(@Clicks0), (@Clicks1), (@Clicks2), (@Clicks3), (@Clicks4), (@Clicks5), (@Clicks6), (@Clicks7), (@Clicks8), (@Clicks9)", sql);
+ }
+ [Fact]
+ public void ExecuteAffrows() {
+ var items = new List();
+ for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now });
+
+ Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows());
+ Assert.Equal(10, insert.AppendData(items).ExecuteAffrows());
+ }
+ [Fact]
+ public void ExecuteIdentity() {
+ var items = new List();
+ for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now });
+
+ Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity());
+ }
+ [Fact]
+ public void ExecuteInserted() {
+ var items = new List();
+ for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now });
+
+ var items2 = insert.AppendData(items).ExecuteInserted();
+ }
+ }
+}
diff --git a/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs
new file mode 100644
index 00000000..ce7d9a2b
--- /dev/null
+++ b/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs
@@ -0,0 +1,501 @@
+using FreeSql.DataAnnotations;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace FreeSql.Tests.SqlServer {
+ public class SqlServerSelectTest {
+
+ ISelect select => g.sqlserver.Select();
+
+ [Table(Name = "tb_topic22")]
+ class Topic {
+ [Column(IsIdentity = true, IsPrimary = true)]
+ public int Id { get; set; }
+ public int Clicks { get; set; }
+ public int TestTypeInfoGuid { get; set; }
+ public TestTypeInfo Type { get; set; }
+ public string Title { get; set; }
+ public DateTime CreateTime { get; set; }
+ }
+ class TestTypeInfo {
+ public int Guid { get; set; }
+ public int ParentId { get; set; }
+ public TestTypeParentInfo Parent { get; set; }
+ public string Name { get; set; }
+ }
+ class TestTypeParentInfo {
+ public int Id { get; set; }
+ public string Name { get; set; }
+
+ public List Types { get; set; }
+ }
+
+ [Fact]
+ public void ToList() {
+ }
+ [Fact]
+ public void ToOne() {
+ }
+ [Fact]
+ public void ToSql() {
+ }
+ [Fact]
+ public void Any() {
+ var count = select.Where(a => 1 == 1).Count();
+ Assert.False(select.Where(a => 1 == 2).Any());
+ Assert.Equal(count > 0, select.Where(a => 1 == 1).Any());
+ }
+ [Fact]
+ public void Count() {
+ var count = select.Where(a => 1 == 1).Count();
+ select.Where(a => 1 == 1).Count(out var count2);
+ Assert.Equal(count, count2);
+ Assert.Equal(0, select.Where(a => 1 == 2).Count());
+ }
+ [Fact]
+ public void Master() {
+ Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql());
+ }
+ [Fact]
+ public void Caching() {
+ var result1 = select.Where(a => 1 == 1).Caching(20, "testcaching").ToList();
+ var testcaching1 = g.sqlserver.Cache.Get("testcaching");
+ Assert.NotNull(testcaching1);
+ var result2 = select.Where(a => 1 == 1).Caching(20, "testcaching").ToList();
+ var testcaching2 = g.sqlserver.Cache.Get("testcaching");
+ Assert.NotNull(testcaching2);
+ Assert.Equal(result1.Count, result1.Count);
+ }
+ [Fact]
+ public void From() {
+ //�������
+ var query2 = select.From((s, b, c) => s
+ .LeftJoin(a => a.TestTypeInfoGuid == b.Guid)
+ .LeftJoin(a => b.ParentId == c.Id)
+ );
+ var sql = query2.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TestTypeInfoGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql);
+ query2.ToList();
+ }
+ [Fact]
+ public void LeftJoin() {
+ //����е�������a.Type��a.Type.Parent ���ǵ�������
+ var query = select.LeftJoin(a => a.Type.Guid == a.TestTypeInfoGuid);
+ var sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid]", sql);
+ query.ToList();
+
+ query = select.LeftJoin(a => a.Type.Guid == a.TestTypeInfoGuid && a.Type.Name == "xxx");
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] AND a__Type.[Name] = 'xxx'", sql);
+ query.ToList();
+
+ query = select.LeftJoin(a => a.Type.Guid == a.TestTypeInfoGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON 1 = 1 LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] AND a__Type.[Name] = 'xxx' WHERE (a__Type__Parent.[Id] = 10)", sql);
+ query.ToList();
+
+ //���û�е�������
+ query = select.LeftJoin((a, b) => b.Guid == a.TestTypeInfoGuid);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid]", sql);
+ query.ToList();
+
+ query = select.LeftJoin((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "xxx");
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'xxx'", sql);
+ query.ToList();
+
+ query = select.LeftJoin((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeParentInfo] b__Parent ON 1 = 1 LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'xxx' WHERE (b__Parent.[Id] = 10)", sql);
+ query.ToList();
+
+ //�������
+ query = select
+ .LeftJoin(a => a.Type.Guid == a.TestTypeInfoGuid)
+ .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql);
+ query.ToList();
+
+ query = select
+ .LeftJoin((a, b) => b.Guid == a.TestTypeInfoGuid)
+ .LeftJoin((a, c) => c.Id == a.Type.ParentId);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] LEFT JOIN [TestTypeParentInfo] c ON c.[Id] = b.[ParentId]", sql);
+ query.ToList();
+
+ //���û�е�������b��c������ϵ
+ var query2 = select.From((s, b, c) => s
+ .LeftJoin(a => a.TestTypeInfoGuid == b.Guid)
+ .LeftJoin(a => b.ParentId == c.Id));
+ sql = query2.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TestTypeInfoGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql);
+ query2.ToList();
+
+ //������϶����㲻��
+ query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid");
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a LEFT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid", sql);
+ query.ToList();
+
+ query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = @bname", new { bname = "xxx" });
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a LEFT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = @bname", sql);
+ query.ToList();
+ }
+ [Fact]
+ public void InnerJoin() {
+ //����е�������a.Type��a.Type.Parent ���ǵ�������
+ var query = select.InnerJoin(a => a.Type.Guid == a.TestTypeInfoGuid);
+ var sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid]", sql);
+ query.ToList();
+
+ query = select.InnerJoin(a => a.Type.Guid == a.TestTypeInfoGuid && a.Type.Name == "xxx");
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] AND a__Type.[Name] = 'xxx'", sql);
+ query.ToList();
+
+ query = select.InnerJoin(a => a.Type.Guid == a.TestTypeInfoGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON 1 = 1 INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] AND a__Type.[Name] = 'xxx' WHERE (a__Type__Parent.[Id] = 10)", sql);
+ query.ToList();
+
+ //���û�е�������
+ query = select.InnerJoin((a, b) => b.Guid == a.TestTypeInfoGuid);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid]", sql);
+ query.ToList();
+
+ query = select.InnerJoin((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "xxx");
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'xxx'", sql);
+ query.ToList();
+
+ query = select.InnerJoin((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeParentInfo] b__Parent ON 1 = 1 INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'xxx' WHERE (b__Parent.[Id] = 10)", sql);
+ query.ToList();
+
+ //�������
+ query = select
+ .InnerJoin(a => a.Type.Guid == a.TestTypeInfoGuid)
+ .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] INNER JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql);
+ query.ToList();
+
+ query = select
+ .InnerJoin((a, b) => b.Guid == a.TestTypeInfoGuid)
+ .InnerJoin((a, c) => c.Id == a.Type.ParentId);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] INNER JOIN [TestTypeParentInfo] c ON c.[Id] = b.[ParentId]", sql);
+ query.ToList();
+
+ //���û�е�������b��c������ϵ
+ var query2 = select.From((s, b, c) => s
+ .InnerJoin(a => a.TestTypeInfoGuid == b.Guid)
+ .InnerJoin(a => b.ParentId == c.Id));
+ sql = query2.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON a.[TestTypeInfoGuid] = b.[Guid] INNER JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql);
+ query2.ToList();
+
+ //������϶����㲻��
+ query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid");
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a INNER JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid", sql);
+ query.ToList();
+
+ query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = @bname", new { bname = "xxx" });
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a INNER JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = @bname", sql);
+ query.ToList();
+
+ }
+ [Fact]
+ public void RightJoin() {
+ //����е�������a.Type��a.Type.Parent ���ǵ�������
+ var query = select.RightJoin(a => a.Type.Guid == a.TestTypeInfoGuid);
+ var sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid]", sql);
+ query.ToList();
+
+ query = select.RightJoin(a => a.Type.Guid == a.TestTypeInfoGuid && a.Type.Name == "xxx");
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] AND a__Type.[Name] = 'xxx'", sql);
+ query.ToList();
+
+ query = select.RightJoin(a => a.Type.Guid == a.TestTypeInfoGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON 1 = 1 RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] AND a__Type.[Name] = 'xxx' WHERE (a__Type__Parent.[Id] = 10)", sql);
+ query.ToList();
+
+ //���û�е�������
+ query = select.RightJoin((a, b) => b.Guid == a.TestTypeInfoGuid);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid]", sql);
+ query.ToList();
+
+ query = select.RightJoin((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "xxx");
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'xxx'", sql);
+ query.ToList();
+
+ query = select.RightJoin((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeParentInfo] b__Parent ON 1 = 1 RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'xxx' WHERE (b__Parent.[Id] = 10)", sql);
+ query.ToList();
+
+ //�������
+ query = select
+ .RightJoin(a => a.Type.Guid == a.TestTypeInfoGuid)
+ .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] RIGHT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql);
+ query.ToList();
+
+ query = select
+ .RightJoin((a, b) => b.Guid == a.TestTypeInfoGuid)
+ .RightJoin((a, c) => c.Id == a.Type.ParentId);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] RIGHT JOIN [TestTypeParentInfo] c ON c.[Id] = b.[ParentId]", sql);
+ query.ToList();
+
+ //���û�е�������b��c������ϵ
+ var query2 = select.From((s, b, c) => s
+ .RightJoin(a => a.TestTypeInfoGuid == b.Guid)
+ .RightJoin(a => b.ParentId == c.Id));
+ sql = query2.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON a.[TestTypeInfoGuid] = b.[Guid] RIGHT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql);
+ query2.ToList();
+
+ //������϶����㲻��
+ query = select.RightJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid");
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a RIGHT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid", sql);
+ query.ToList();
+
+ query = select.RightJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = @bname", new { bname = "xxx" });
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a RIGHT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = @bname", sql);
+ query.ToList();
+
+ }
+ [Fact]
+ public void Where() {
+ //����е�������a.Type��a.Type.Parent ���ǵ�������
+ var query = select.Where(a => a.Id == 10);
+ var sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a WHERE (a.[Id] = 10)", sql);
+ query.ToList();
+
+ query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a WHERE (a.[Id] = 10 AND a.[Id] > 10 OR a.[Clicks] > 100)", sql);
+ query.ToList();
+
+ query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a WHERE (a.[Id] = 10) AND (a.[Clicks] > 100)", sql);
+ query.ToList();
+
+ query = select.Where(a => a.Type.Name == "typeTitle");
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a, [TestTypeInfo] a__Type WHERE (a__Type.[Name] = 'typeTitle')", sql);
+ query.ToList();
+
+ query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TestTypeInfoGuid);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a, [TestTypeInfo] a__Type WHERE (a__Type.[Name] = 'typeTitle' AND a__Type.[Guid] = a.[TestTypeInfoGuid])", sql);
+ query.ToList();
+
+ query = select.Where(a => a.Type.Parent.Name == "tparent");
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a, [TestTypeInfo] a__Type, [TestTypeParentInfo] a__Type__Parent WHERE (a__Type__Parent.[Name] = 'tparent')", sql);
+ query.ToList();
+
+ //���û�е������ԣ��������
+ query = select.Where((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "typeTitle");
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'typeTitle')", sql);
+ query.ToList();
+
+ query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TestTypeInfoGuid);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Name] = 'typeTitle' AND b.[Guid] = a.[TestTypeInfoGuid])", sql);
+ query.ToList();
+
+ query = select.Where((a, b, c) => c.Name == "tparent");
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a, [TestTypeParentInfo] c WHERE (c.[Name] = 'tparent')", sql);
+ query.ToList();
+
+ //����һ�� From ��Ķ������
+ var query2 = select.From((s, b, c) => s
+ .Where(a => a.Id == 10 && c.Name == "xxx")
+ .Where(a => b.ParentId == 20));
+ sql = query2.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a, [TestTypeParentInfo] c, [TestTypeInfo] b WHERE (a.[Id] = 10 AND c.[Name] = 'xxx') AND (b.[ParentId] = 20)", sql);
+ query2.ToList();
+
+ //������϶����㲻��
+ query = select.Where("a.clicks > 100 and a.id = @id", new { id = 10 });
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a WHERE (a.clicks > 100 and a.id = @id)", sql);
+ query.ToList();
+ }
+ [Fact]
+ public void WhereIf() {
+ //����е�������a.Type��a.Type.Parent ���ǵ�������
+ var query = select.WhereIf(true, a => a.Id == 10);
+ var sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a WHERE (a.[Id] = 10)", sql);
+ query.ToList();
+
+ query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a WHERE (a.[Id] = 10 AND a.[Id] > 10 OR a.[Clicks] > 100)", sql);
+ query.ToList();
+
+ query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a WHERE (a.[Id] = 10) AND (a.[Clicks] > 100)", sql);
+ query.ToList();
+
+ query = select.WhereIf(true, a => a.Type.Name == "typeTitle");
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a, [TestTypeInfo] a__Type WHERE (a__Type.[Name] = 'typeTitle')", sql);
+ query.ToList();
+
+ query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TestTypeInfoGuid);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a, [TestTypeInfo] a__Type WHERE (a__Type.[Name] = 'typeTitle' AND a__Type.[Guid] = a.[TestTypeInfoGuid])", sql);
+ query.ToList();
+
+ query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent");
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a, [TestTypeInfo] a__Type, [TestTypeParentInfo] a__Type__Parent WHERE (a__Type__Parent.[Name] = 'tparent')", sql);
+ query.ToList();
+
+ //����һ�� From ��Ķ������
+ var query2 = select.From((s, b, c) => s
+ .WhereIf(true, a => a.Id == 10 && c.Name == "xxx")
+ .WhereIf(true, a => b.ParentId == 20));
+ sql = query2.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a, [TestTypeParentInfo] c, [TestTypeInfo] b WHERE (a.[Id] = 10 AND c.[Name] = 'xxx') AND (b.[ParentId] = 20)", sql);
+ query2.ToList();
+
+ //������϶����㲻��
+ query = select.WhereIf(true, "a.clicks > 100 and a.id = @id", new { id = 10 });
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a WHERE (a.clicks > 100 and a.id = @id)", sql);
+ query.ToList();
+
+ // ==========================================WhereIf(false)
+
+ //����е�������a.Type��a.Type.Parent ���ǵ�������
+ query = select.WhereIf(false, a => a.Id == 10);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a", sql);
+ query.ToList();
+
+ query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a", sql);
+ query.ToList();
+
+ query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a", sql);
+ query.ToList();
+
+ query = select.WhereIf(false, a => a.Type.Name == "typeTitle");
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a", sql);
+ query.ToList();
+
+ query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TestTypeInfoGuid);
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a", sql);
+ query.ToList();
+
+ query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent");
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a", sql);
+ query.ToList();
+
+ //����һ�� From ��Ķ������
+ query2 = select.From((s, b, c) => s
+ .WhereIf(false, a => a.Id == 10 && c.Name == "xxx")
+ .WhereIf(false, a => b.ParentId == 20));
+ sql = query2.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a", sql);
+ query2.ToList();
+
+ //������϶����㲻��
+ query = select.WhereIf(false, "a.clicks > 100 and a.id = @id", new { id = 10 });
+ sql = query.ToSql().Replace("\r\n", "");
+ Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a", sql);
+ query.ToList();
+ }
+ [Fact]
+ public void WhereLike() {
+ //ģ����ѯ��WhereLike(a => a.Title, "%sql")
+ var query = select.Where(a => a.Title.StartsWith("ss")).Where(a => a.Type.Name.Contains("sss"));
+ var sql = query.ToSql().Replace("\r\n", "");
+
+ query = select.Where(a => a.Title.EndsWith("ss"));
+ sql = query.ToSql().Replace("\r\n", "");
+
+ query = select.Where(a => a.Title.Contains("ss"));
+ sql = query.ToSql().Replace("\r\n", "");
+
+ query = select.WhereLike(a => a.Title, "%ss");
+ sql = query.ToSql().Replace("\r\n", "");
+
+ query = select.WhereLike(a => a.Title, "%ss").WhereLike(a => a.Title, "%aa");
+ sql = query.ToSql().Replace("\r\n", "");
+
+ //ģ����ѯ��ѡ������ OR��WhereLike(a => new[] { a.Title, a.Content }, "%sql%")
+ query = select.WhereLike(a => new[] { a.Title, a.Type.Name, a.Type.Parent.Name }, "%aa");
+ sql = query.ToSql().Replace("\r\n", "");
+ }
+ [Fact]
+ public void GroupBy() {
+ }
+ [Fact]
+ public void Having() {
+ }
+ [Fact]
+ public void OrderBy() {
+ }
+ [Fact]
+ public void Skip_Offset() {
+ }
+ [Fact]
+ public void Take_Limit() {
+ }
+ [Fact]
+ public void Page() {
+ }
+ [Fact]
+ public void Sum() {
+ }
+ [Fact]
+ public void Min() {
+ }
+ [Fact]
+ public void Max() {
+ }
+ [Fact]
+ public void Avg() {
+ }
+ [Fact]
+ public void As() {
+ }
+ }
+}
diff --git a/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs
new file mode 100644
index 00000000..3775b110
--- /dev/null
+++ b/FreeSql.Tests/SqlServer/Curd/SqlServerUpdateTest.cs
@@ -0,0 +1,107 @@
+using FreeSql.DataAnnotations;
+using System;
+using System.Collections.Generic;
+using Xunit;
+
+namespace FreeSql.Tests.SqlServer {
+ public class SqlServerUpdateTest {
+ IUpdate update => g.sqlserver.Update();
+
+ [Table(Name = "tb_topic")]
+ class Topic {
+ [Column(IsIdentity = true, IsPrimary = true)]
+ public int Id { get; set; }
+ public int? Clicks { get; set; }
+ public TestTypeInfo Type { get; set; }
+ public string Title { get; set; }
+ public DateTime CreateTime { get; set; }
+ }
+
+ [Fact]
+ public void Dywhere() {
+ Assert.Null(g.sqlserver.Update().ToSql());
+ Assert.Equal("UPDATE [tb_topic] SET title='test' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.sqlserver.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql());
+ Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql());
+ Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1 OR [Id] = 2)", g.sqlserver.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql());
+ Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new { id = 1 }).SetRaw("title='test1'").ToSql());
+ }
+
+ [Fact]
+ public void SetSource() {
+ var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", "");
+ Assert.Equal("UPDATE [tb_topic] SET [Clicks] = @p_0, [Title] = @p_1, [CreateTime] = @p_2 WHERE ([Id] = 1)", sql);
+
+ var items = new List();
+ for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 });
+
+ sql = update.SetSource(items).ToSql().Replace("\r\n", "");
+ Assert.Equal("UPDATE [tb_topic] SET [Clicks] = CASE [Id] WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, [Title] = CASE [Id] WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, [CreateTime] = CASE [Id] WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql);
+
+ sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", "");
+ Assert.Equal("UPDATE [tb_topic] SET [Title] = CASE [Id] WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql);
+
+ sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020,1,1)).ToSql().Replace("\r\n", "");
+ Assert.Equal("UPDATE [tb_topic] SET [CreateTime] = @p_0 WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql);
+ }
+ [Fact]
+ public void IgnoreColumns() {
+ var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", "");
+ Assert.Equal("UPDATE [tb_topic] SET [Title] = @p_0 WHERE ([Id] = 1)", sql);
+ }
+ [Fact]
+ public void Set() {
+ var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", "");
+ Assert.Equal("UPDATE [tb_topic] SET [Title] = @p_0 WHERE ([Id] = 1)", sql);
+
+ sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", "");
+ Assert.Equal("UPDATE [tb_topic] SET [Title] = @p_0, [CreateTime] = @p_1 WHERE ([Id] = 1)", sql);
+
+ sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", "");
+ Assert.Equal("UPDATE [tb_topic] SET [Clicks] = isnull([Clicks], 0) * 10 / 1 WHERE ([Id] = 1)", sql);
+
+ sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", "");
+ Assert.Equal("UPDATE [tb_topic] SET [Id] = [Id] - 10 WHERE ([Id] = 1)", sql);
+
+ int incrv = 10;
+ sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", "");
+ Assert.Equal("UPDATE [tb_topic] SET [Clicks] = isnull([Clicks], 0) * 10 / 1 WHERE ([Id] = 1)", sql);
+
+ sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", "");
+ Assert.Equal("UPDATE [tb_topic] SET [Id] = [Id] - 10 WHERE ([Id] = 1)", sql);
+ }
+ [Fact]
+ public void SetRaw() {
+ var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + @incrClick", new { incrClick = 1 }).ToSql().Replace("\r\n", "");
+ Assert.Equal("UPDATE [tb_topic] SET clicks = clicks + @incrClick WHERE ([Id] = 1)", sql);
+ }
+ [Fact]
+ public void Where() {
+ var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", "");
+ Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] = 1)", sql);
+
+ sql = update.Where("id = @id", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", "");
+ Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE (id = @id)", sql);
+
+ var item = new Topic { Id = 1, Title = "newtitle" };
+ sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", "");
+ Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] = 1)", sql);
+
+ var items = new List();
+ for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 });
+ sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", "");
+ Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql);
+ }
+ [Fact]
+ public void WhereExists() {
+
+ }
+ [Fact]
+ public void ExecuteAffrows() {
+
+ }
+ [Fact]
+ public void ExecuteUpdated() {
+
+ }
+ }
+}
diff --git a/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs b/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs
new file mode 100644
index 00000000..4970d9be
--- /dev/null
+++ b/FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs
@@ -0,0 +1,55 @@
+using FreeSql.DataAnnotations;
+using System;
+using Xunit;
+
+namespace FreeSql.Tests.SqlServer {
+ public class SqlServerAdoTest {
+ [Fact]
+ public void Pool() {
+ var t1 = g.sqlserver.Ado.MasterPool.StatisticsFullily;
+ }
+
+ [Fact]
+ public void SlavePools() {
+ var t2 = g.sqlserver.Ado.SlavePools.Count;
+ }
+
+ [Fact]
+ public void IsTracePerformance() {
+ Assert.True(g.sqlserver.Ado.IsTracePerformance);
+ }
+
+ [Fact]
+ public void ExecuteReader() {
+
+ }
+ [Fact]
+ public void ExecuteArray() {
+
+ }
+ [Fact]
+ public void ExecuteNonQuery() {
+
+ }
+ [Fact]
+ public void ExecuteScalar() {
+
+ }
+
+ [Fact]
+ public void Query() {
+ var t3 = g.sqlserver.Ado.Query("select * from song");
+
+ var t4 = g.sqlserver.Ado.Query<(int, string, string, DateTime)>("select * from song");
+
+ var t5 = g.sqlserver.Ado.Query("select * from song");
+ }
+
+ class xxx {
+ public int Id { get; set; }
+ public string Title { get; set; }
+ public string Url { get; set; }
+ public DateTime Create_time { get; set; }
+ }
+ }
+}
diff --git a/FreeSql.Tests/g.cs b/FreeSql.Tests/g.cs
index 1f7f39b0..471df841 100644
--- a/FreeSql.Tests/g.cs
+++ b/FreeSql.Tests/g.cs
@@ -10,6 +10,6 @@ public class g {
.Build();
public static IFreeSql sqlserver = new FreeSql.FreeSqlBuilder()
- .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=shop;Pooling=true;Max Pool Size=10")
+ .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=cms;Pooling=true;Max Pool Size=10")
.Build();
}
diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs
index facc2e02..cee3ec4a 100644
--- a/FreeSql/Interface/IAdo.cs
+++ b/FreeSql/Interface/IAdo.cs
@@ -80,6 +80,15 @@ namespace FreeSql {
///
object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
+ ///
+ /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 })
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ List Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
///
/// 执行SQL返回对象集合,Query<User>("select * from user where age > @age", new { age = 25 })
///
@@ -126,7 +135,16 @@ namespace FreeSql {
Task