- 修复 实体类型为 char 时 ExpressionTree 读取失败 bug;#283

- 修复 表达式解析 Include 父子导航可能失败的 bug;
This commit is contained in:
28810 2020-04-22 14:37:30 +08:00
parent 7311ae600c
commit c78c4ed7ae
7 changed files with 382 additions and 22 deletions

View File

@ -120,6 +120,13 @@
清空状态数据 清空状态数据
</summary> </summary>
</member> </member>
<member name="M:FreeSql.DbSet`1.RemoveAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
<summary>
根据 lambda 条件删除数据
</summary>
<param name="predicate"></param>
<returns></returns>
</member>
<member name="M:FreeSql.DbSet`1.Add(`0)"> <member name="M:FreeSql.DbSet`1.Add(`0)">
<summary> <summary>
添加 添加
@ -450,5 +457,14 @@
<param name="that"></param> <param name="that"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])">
<summary>
批量注入 Repository可以参考代码自行调整
</summary>
<param name="services"></param>
<param name="globalDataFilter"></param>
<param name="assemblies"></param>
<returns></returns>
</member>
</members> </members>
</doc> </doc>

View File

@ -0,0 +1,75 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具 FreeSql.Generator 生成。
// 运行时版本:3.1.0
// Website: https://github.com/2881099/FreeSql
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using FreeSql.DataAnnotations;
namespace FreeSql.Jhfw.Models {
public interface IBaseModel<TKey>
{
TKey Id { get; set; }
}
[JsonObject(MemberSerialization.OptIn), Table(Name = "bank_outlets")]
public partial class BankOutlets : IBaseModel<int>
{
[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<BankOutlets> ManyBankOutlets { get; set; }
#endregion
#region => ManyToMany
#endregion
}
}

View File

@ -0,0 +1,66 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具 FreeSql.Generator 生成。
// 运行时版本:3.1.0
// Website: https://github.com/2881099/FreeSql
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
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<int>
{
[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<BankOutlets> ManyBankOutlets { get; set; }
#endregion
#region => ManyToMany
#endregion
}
}

View File

@ -32,6 +32,11 @@ namespace FreeSql.Tests.MySqlConnector
public void Test1() public void Test1()
{ {
g.mysql.Select<TestAddEnum>().ToList(); g.mysql.Select<TestAddEnum>().ToList();
var soc = g.mysql.GetRepository<Jhfw.Models.BankOutlets, int>();
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();
} }
} }
} }

View File

@ -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<BuildDictionary>().Where("1=1").ExecuteAffrows();
db.Delete<Build2>().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<Build2>()
.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; }
}
}
}

View File

@ -287,6 +287,7 @@ namespace FreeSql.Internal.CommonProvider
if (tb == null) throw new Exception("Include 参数类型错误"); if (tb == null) throw new Exception("Include 参数类型错误");
_isIncluded = true; _isIncluded = true;
_tables[0].Parameter = navigateSelector.Parameters[0];
_commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(expBody, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null, null, null); _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(expBody, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null, null, null);
return this; return this;
} }

View File

@ -1236,6 +1236,7 @@ namespace FreeSql.Internal
public static PropertyInfo PropertyDataIndex = typeof(RowInfo).GetProperty("DataIndex"); public static PropertyInfo PropertyDataIndex = typeof(RowInfo).GetProperty("DataIndex");
} }
internal static MethodInfo MethodDataReaderGetValue = typeof(Utils).GetMethod("InternalDataReaderGetValue", BindingFlags.Static | BindingFlags.NonPublic); 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) internal static object InternalDataReaderGetValue(CommonUtils commonUtil, DbDataReader dr, int index)
{ {
if (commonUtil._orm.Ado.DataType == DataType.Dameng && dr.IsDBNull(index)) return null; if (commonUtil._orm.Ado.DataType == DataType.Dameng && dr.IsDBNull(index)) return null;
@ -1335,7 +1336,7 @@ namespace FreeSql.Internal
return Expression.Lambda<Func<Type, int[], DbDataReader, int, CommonUtils, RowInfo>>( return Expression.Lambda<Func<Type, int[], DbDataReader, int, CommonUtils, RowInfo>>(
Expression.Block(new[] { ret2Exp, read2Exp }, block2Exp), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile(); 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<Func<Type, int[], DbDataReader, int, CommonUtils, RowInfo>>( return Expression.Lambda<Func<Type, int[], DbDataReader, int, CommonUtils, RowInfo>>(
Expression.Block( Expression.Block(
Expression.IfThen( Expression.IfThen(