diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml
index 2c69043d..9f17feac 100644
--- a/FreeSql.DbContext/FreeSql.DbContext.xml
+++ b/FreeSql.DbContext/FreeSql.DbContext.xml
@@ -120,6 +120,13 @@
清空状态数据
+
+
+ 根据 lambda 条件删除数据
+
+
+
+
添加
@@ -450,5 +457,14 @@
+
+
+ 批量注入 Repository,可以参考代码自行调整
+
+
+
+
+
+
diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/BankOutlets.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/BankOutlets.cs
new file mode 100644
index 00000000..25ab8b30
--- /dev/null
+++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/BankOutlets.cs
@@ -0,0 +1,75 @@
+//------------------------------------------------------------------------------
+//
+// 此代码由工具 FreeSql.Generator 生成。
+// 运行时版本:3.1.0
+// Website: https://github.com/2881099/FreeSql
+// 对此文件的更改可能会导致不正确的行为,并且如果
+// 重新生成代码,这些更改将会丢失。
+//
+//------------------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using FreeSql.DataAnnotations;
+namespace FreeSql.Jhfw.Models {
+
+ public interface IBaseModel
+ {
+ TKey Id { get; set; }
+ }
+ [JsonObject(MemberSerialization.OptIn), Table(Name = "bank_outlets")]
+ public partial class BankOutlets : IBaseModel
+ {
+
+ [JsonProperty]
+ public int? BankId { get => _BankId; set {
+ if (_BankId == value) return;
+ _BankId = value;
+ OneBanks = null;
+ }}
+ private int? _BankId;
+
+ [JsonProperty]
+ public int? ParentId { get => _ParentId; set {
+ if (_ParentId == value) return;
+ _ParentId = value;
+ OneBankOutlets = null;
+ }}
+ private int? _ParentId;
+
+ [JsonProperty]
+ public string Address { get; set; } = "";
+
+ [JsonProperty, Column(DbType = "varchar(50)")]
+ public string Area { get; set; } = "";
+
+ [JsonProperty, Column(Name = "ID", IsIdentity = true)]
+ public int Id { get; set; }
+
+ [JsonProperty, Column(DbType = "varchar(50)")]
+ public string Name { get; set; } = "";
+
+
+ #region 外键 => 导航属性,ManyToOne/OneToOne
+
+ [Navigate("BankId")]
+ public virtual Banks OneBanks { get; set; }
+
+ [Navigate("ParentId")]
+ public virtual BankOutlets OneBankOutlets { get; set; }
+
+ #endregion
+
+ #region 外键 => 导航属性,OneToMany
+
+ [Navigate("ParentId")]
+ public virtual List ManyBankOutlets { get; set; }
+
+ #endregion
+
+ #region 外键 => 导航属性,ManyToMany
+
+ #endregion
+ }
+
+}
diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/Banks.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/Banks.cs
new file mode 100644
index 00000000..17f26cdb
--- /dev/null
+++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/Banks.cs
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// 此代码由工具 FreeSql.Generator 生成。
+// 运行时版本:3.1.0
+// Website: https://github.com/2881099/FreeSql
+// 对此文件的更改可能会导致不正确的行为,并且如果
+// 重新生成代码,这些更改将会丢失。
+//
+//------------------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using FreeSql.DataAnnotations;
+namespace FreeSql.Jhfw.Models {
+
+ [JsonObject(MemberSerialization.OptIn), Table(Name = "banks")]
+ public partial class Banks : IBaseModel
+ {
+
+ [JsonProperty, Column(DbType = "datetime")]
+ public DateTime? Addtime { get; set; }
+
+ [JsonProperty, Column(DbType = "varchar(250)")]
+ public string Banner { get; set; } = "";
+
+ [JsonProperty, Column(DbType = "varchar(20)")]
+ public string City { get; set; } = "";
+
+ [JsonProperty, Column(Name = "ID", IsIdentity = true)]
+ public int Id { get; set; }
+
+ [JsonProperty, Column(DbType = "tinyint(1)")]
+ public bool IsDelete { get; set; }
+
+ [JsonProperty, Column(DbType = "tinyint(1)")]
+ public bool IsGrab { get; set; }
+
+ [JsonProperty, Column(DbType = "tinyint(1)")]
+ public bool IsJoinHmd { get; set; }
+
+ [JsonProperty, Column(DbType = "varchar(100)")]
+ public string LoanType { get; set; } = "";
+
+ [JsonProperty, Column(DbType = "varchar(250)")]
+ public string Logo { get; set; } = "";
+
+ [JsonProperty]
+ public string Name { get; set; } = "";
+
+ [JsonProperty, Column(DbType = "varchar(3000)")]
+ public string Notice { get; set; } = "";
+
+
+ #region 外键 => 导航属性,OneToMany
+
+ [Navigate("BankId")]
+ public virtual List ManyBankOutlets { get; set; }
+
+ #endregion
+
+ #region 外键 => 导航属性,ManyToMany
+
+ #endregion
+ }
+
+}
diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/UnitTest1.cs
index d3300f9b..fa20bfdd 100644
--- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/UnitTest1.cs
+++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/UnitTest1.cs
@@ -32,6 +32,11 @@ namespace FreeSql.Tests.MySqlConnector
public void Test1()
{
g.mysql.Select().ToList();
+
+
+ var soc = g.mysql.GetRepository();
+ var item1 = soc.Where(d => d.Id == 1).Include(x => x.OneBankOutlets).Include(d => d.OneBanks).First();
+ var item2 = soc.Where(d => d.Id == 1).Include(d => d.OneBanks).Include(x => x.OneBankOutlets).First();
}
}
}
diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/283.cs b/FreeSql.Tests/FreeSql.Tests/Issues/283.cs
new file mode 100644
index 00000000..1fd3ecf1
--- /dev/null
+++ b/FreeSql.Tests/FreeSql.Tests/Issues/283.cs
@@ -0,0 +1,196 @@
+using FreeSql.DataAnnotations;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Xunit;
+
+namespace FreeSql.Tests.Issues
+{
+ public class _283
+ {
+ [Fact]
+ public void SelectTest()
+ {
+ IFreeSql db = g.sqlserver;
+
+ db.Transaction(() =>
+ {
+ db.Delete().Where("1=1").ExecuteAffrows();
+ db.Delete().Where("1=1").ExecuteAffrows();
+
+ var dictionaries = new BuildDictionary[]
+ {
+ new BuildDictionary { Type = 1, Code = 'A', Name = "办公建筑" },
+ new BuildDictionary { Type = 1, Code = 'B', Name = "商场建筑" },
+ new BuildDictionary { Type = 1, Code = 'C', Name = "宾馆饭店建筑" },
+ new BuildDictionary { Type = 1, Code = 'D', Name = "文化教育建筑" },
+ new BuildDictionary { Type = 1, Code = 'E', Name = "医疗卫生建筑" },
+ new BuildDictionary { Type = 1, Code = 'F', Name = "体育建筑" },
+ new BuildDictionary { Type = 1, Code = 'G', Name = "综合建筑" },
+ new BuildDictionary { Type = 1, Code = 'Z', Name = "其他建筑" },
+
+ new BuildDictionary { Type = 2, Code = 'A', Name = "结构建筑" },
+ new BuildDictionary { Type = 2, Code = 'B', Name = "框剪结构" },
+ new BuildDictionary { Type = 2, Code = 'C', Name = "剪力墙结构" },
+ new BuildDictionary { Type = 2, Code = 'D', Name = "砖混结构" },
+ new BuildDictionary { Type = 2, Code = 'E', Name = "钢结构" },
+ new BuildDictionary { Type = 2, Code = 'F', Name = "筒体结构" },
+ new BuildDictionary { Type = 2, Code = 'G', Name = "木结构" },
+ new BuildDictionary { Type = 2, Code = 'Z', Name = "其他" },
+
+ new BuildDictionary { Type = 3, Code = 'A', Name = "集中式全空气系统" },
+ new BuildDictionary { Type = 3, Code = 'B', Name = "风机盘管+新风系统" },
+ new BuildDictionary { Type = 3, Code = 'C', Name = "分体式空调或 VRV 的局部式机组系统" },
+ new BuildDictionary { Type = 3, Code = 'Z', Name = "其他" },
+
+ new BuildDictionary { Type = 4, Code = 'A', Name = "散热器采暖" },
+ new BuildDictionary { Type = 4, Code = 'B', Name = "地板辐射采暖" },
+ new BuildDictionary { Type = 4, Code = 'C', Name = "电辐射采暖" },
+ new BuildDictionary { Type = 4, Code = 'D', Name = "空调系统集中供暖" },
+ new BuildDictionary { Type = 4, Code = 'Z', Name = "其他" },
+
+ new BuildDictionary { Type = 5, Code = 'A', Name = "砖" },
+ new BuildDictionary { Type = 5, Code = 'B', Name = "建筑砌块" },
+ new BuildDictionary { Type = 5, Code = 'C', Name = "板材墙体" },
+ new BuildDictionary { Type = 5, Code = 'D', Name = "复合墙板和墙体" },
+ new BuildDictionary { Type = 5, Code = 'E', Name = "玻璃幕墙" },
+ new BuildDictionary { Type = 5, Code = 'Z', Name = "其他" },
+
+ new BuildDictionary { Type = 6, Code = 'A', Name = "内保温" },
+ new BuildDictionary { Type = 6, Code = 'B', Name = "外保温" },
+ new BuildDictionary { Type = 6, Code = 'C', Name = "夹芯保温" },
+ new BuildDictionary { Type = 6, Code = 'Z', Name = "其他" },
+
+ new BuildDictionary { Type = 7, Code = 'A', Name = "单玻单层窗" },
+ new BuildDictionary { Type = 7, Code = 'B', Name = "单玻双层窗" },
+ new BuildDictionary { Type = 7, Code = 'C', Name = "单玻单层窗+单玻双层窗" },
+ new BuildDictionary { Type = 7, Code = 'D', Name = "中空双层玻璃窗" },
+ new BuildDictionary { Type = 7, Code = 'E', Name = "中空三层玻璃窗" },
+ new BuildDictionary { Type = 7, Code = 'F', Name = "中空充惰性气体" },
+ new BuildDictionary { Type = 7, Code = 'Z', Name = "其他" },
+
+ new BuildDictionary { Type = 8, Code = 'A', Name = "普通玻璃" },
+ new BuildDictionary { Type = 8, Code = 'B', Name = "镀膜玻璃" },
+ new BuildDictionary { Type = 8, Code = 'C', Name = "Low-e 玻璃" },
+ new BuildDictionary { Type = 8, Code = 'Z', Name = "其他" },
+
+ new BuildDictionary { Type = 9, Code = 'A', Name = "钢窗" },
+ new BuildDictionary { Type = 9, Code = 'B', Name = "铝合金" },
+ new BuildDictionary { Type = 9, Code = 'C', Name = "木窗" },
+ new BuildDictionary { Type = 9, Code = 'D', Name = "断热窗框" },
+ new BuildDictionary { Type = 9, Code = 'E', Name = "塑钢" },
+ new BuildDictionary { Type = 9, Code = 'Z', Name = "其他" },
+ };
+
+ db.Insert(dictionaries).ExecuteAffrows();
+
+ Build2 build = new Build2
+ {
+ ID = 1,
+ Name = "建筑 1",
+ BuildFunctionCode = 'A',
+ BuildStructureCode = 'A',
+ AirTypeCode = 'A',
+ HeatTypeCode = 'A',
+ WallMaterialTypeCode = 'A',
+ WallWarmTypeCode = 'A',
+ WallWindowsTypeCode = 'A',
+ GlassTypeCode = 'A',
+ WinFrameMaterialCode = 'A'
+ };
+
+ db.Insert(build).ExecuteAffrows();
+ });
+
+ Build2 build = db.Select()
+ .InnerJoin(a => a.BuildFunctionCode == a.BuildFunction.Code && a.BuildFunction.Type == 1)
+ .InnerJoin(a => a.BuildStructureCode == a.BuildStructure.Code && a.BuildStructure.Type == 2)
+ .InnerJoin(a => a.AirTypeCode == a.AirType.Code && a.AirType.Type == 3)
+ .InnerJoin(a => a.HeatTypeCode == a.HeatType.Code && a.HeatType.Type == 4)
+ .InnerJoin(a => a.WallMaterialTypeCode == a.WallMaterialType.Code && a.WallMaterialType.Type == 5)
+ .InnerJoin(a => a.WallWarmTypeCode == a.WallWarmType.Code && a.WallWarmType.Type == 6)
+ .InnerJoin(a => a.WallWindowsTypeCode == a.WallWindowsType.Code && a.WallWindowsType.Type == 7)
+ .InnerJoin(a => a.GlassTypeCode == a.GlassType.Code && a.GlassType.Type == 8)
+ .InnerJoin(a => a.WinFrameMaterialCode == a.WinFrameMaterial.Code && a.WinFrameMaterial.Type == 9)
+ .Where(a => a.ID == 1)
+ .ToOne();
+
+ Assert.NotNull(build);
+ }
+
+ [Table(Name = "F_Build2")]
+ public class Build2
+ {
+ public int ID { get; set; }
+
+ public string Name { get; set; }
+
+ [Column(MapType = typeof(string), DbType = "char")]
+ public char BuildFunctionCode { get; set; }
+
+ [Navigate(nameof(BuildFunctionCode))]
+ public BuildDictionary BuildFunction { get; set; }
+
+ [Column(MapType = typeof(string), DbType = "char")]
+ public char BuildStructureCode { get; set; }
+
+ [Navigate(nameof(BuildStructureCode))]
+ public BuildDictionary BuildStructure { get; set; }
+
+ [Column(MapType = typeof(string), DbType = "char")]
+ public char AirTypeCode { get; set; }
+
+ [Navigate(nameof(AirTypeCode))]
+ public BuildDictionary AirType { get; set; }
+
+ [Column(MapType = typeof(string), DbType = "char")]
+ public char HeatTypeCode { get; set; }
+
+ [Navigate(nameof(HeatTypeCode))]
+ public BuildDictionary HeatType { get; set; }
+
+ [Column(MapType = typeof(string), DbType = "char")]
+ public char WallMaterialTypeCode { get; set; }
+
+ [Navigate(nameof(WallMaterialTypeCode))]
+ public BuildDictionary WallMaterialType { get; set; }
+
+ [Column(MapType = typeof(string), DbType = "char")]
+ public char WallWarmTypeCode { get; set; }
+
+ [Navigate(nameof(WallWarmTypeCode))]
+ public BuildDictionary WallWarmType { get; set; }
+
+ [Column(MapType = typeof(string), DbType = "char")]
+ public char WallWindowsTypeCode { get; set; }
+
+ [Navigate(nameof(WallWindowsTypeCode))]
+ public BuildDictionary WallWindowsType { get; set; }
+
+ [Column(MapType = typeof(string), DbType = "char")]
+ public char GlassTypeCode { get; set; }
+
+ [Navigate(nameof(GlassTypeCode))]
+ public BuildDictionary GlassType { get; set; }
+
+ [Column(MapType = typeof(string), DbType = "char")]
+ public char WinFrameMaterialCode { get; set; }
+
+ [Navigate(nameof(WinFrameMaterialCode))]
+ public BuildDictionary WinFrameMaterial { get; set; }
+ }
+
+ [Table(Name = "F_BuildDictionary")]
+ public class BuildDictionary
+ {
+ [Column(IsPrimary = true)]
+ public int Type { get; set; }
+
+ [Column(IsPrimary = true, MapType = typeof(string), DbType = "char")]
+ public char Code { get; set; }
+
+ [Column(StringLength = 20, IsNullable = false)]
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs
index 48714a49..3870966f 100644
--- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs
+++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs
@@ -287,6 +287,7 @@ namespace FreeSql.Internal.CommonProvider
if (tb == null) throw new Exception("Include 参数类型错误");
_isIncluded = true;
+ _tables[0].Parameter = navigateSelector.Parameters[0];
_commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(expBody, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null, null, null);
return this;
}
diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs
index 98f4a128..5ea91584 100644
--- a/FreeSql/Internal/UtilsExpressionTree.cs
+++ b/FreeSql/Internal/UtilsExpressionTree.cs
@@ -1236,6 +1236,7 @@ namespace FreeSql.Internal
public static PropertyInfo PropertyDataIndex = typeof(RowInfo).GetProperty("DataIndex");
}
internal static MethodInfo MethodDataReaderGetValue = typeof(Utils).GetMethod("InternalDataReaderGetValue", BindingFlags.Static | BindingFlags.NonPublic);
+ internal static PropertyInfo PropertyDataReaderFieldCount = typeof(DbDataReader).GetProperty("FieldCount");
internal static object InternalDataReaderGetValue(CommonUtils commonUtil, DbDataReader dr, int index)
{
if (commonUtil._orm.Ado.DataType == DataType.Dameng && dr.IsDBNull(index)) return null;
@@ -1309,33 +1310,33 @@ namespace FreeSql.Internal
}
}
block2Exp.AddRange(new Expression[] {
- //Expression.TryCatch(Expression.Block(
- // typeof(void),
- Expression.Assign(read2Exp, read2ExpAssign),
- Expression.IfThen(Expression.GreaterThan(read2ExpDataIndex, dataIndexExp),
- Expression.Assign(dataIndexExp, read2ExpDataIndex)),
- Expression.IfThenElse(Expression.Equal(read2ExpValue, Expression.Constant(null)),
- Expression.Assign(Expression.MakeMemberAccess(ret2Exp, field), Expression.Default(field.FieldType)),
- Expression.Assign(Expression.MakeMemberAccess(ret2Exp, field), Expression.Convert(read2ExpValue, field.FieldType)))
- //),
- //Expression.Catch(typeof(Exception), Expression.Block(
- // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(0)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 0)))),
- // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(1)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 1)))),
- // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(2)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 2)))),
- // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(3)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 3)))),
- // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(4)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 4))))
- // )
- //))
- });
+ //Expression.TryCatch(Expression.Block(
+ // typeof(void),
+ Expression.Assign(read2Exp, read2ExpAssign),
+ Expression.IfThen(Expression.GreaterThan(read2ExpDataIndex, dataIndexExp),
+ Expression.Assign(dataIndexExp, read2ExpDataIndex)),
+ Expression.IfThenElse(Expression.Equal(read2ExpValue, Expression.Constant(null)),
+ Expression.Assign(Expression.MakeMemberAccess(ret2Exp, field), Expression.Default(field.FieldType)),
+ Expression.Assign(Expression.MakeMemberAccess(ret2Exp, field), Expression.Convert(read2ExpValue, field.FieldType)))
+ //),
+ //Expression.Catch(typeof(Exception), Expression.Block(
+ // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(0)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 0)))),
+ // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(1)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 1)))),
+ // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(2)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 2)))),
+ // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(3)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 3)))),
+ // Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(4)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 4))))
+ // )
+ //))
+ });
}
block2Exp.AddRange(new Expression[] {
- Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, Expression.Convert(ret2Exp, typeof(object)), dataIndexExp)),
- Expression.Label(returnTarget, Expression.Default(typeof(RowInfo)))
- });
+ Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, Expression.Convert(ret2Exp, typeof(object)), dataIndexExp)),
+ Expression.Label(returnTarget, Expression.Default(typeof(RowInfo)))
+ });
return Expression.Lambda>(
Expression.Block(new[] { ret2Exp, read2Exp }, block2Exp), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile();
}
- var rowLenExp = Expression.ArrayLength(rowExp);
+ var rowLenExp = Expression.MakeMemberAccess(rowExp, PropertyDataReaderFieldCount);
return Expression.Lambda>(
Expression.Block(
Expression.IfThen(