补充 ISelect.ToList(a => new XxxDto { XxxId = a.Id, ... }) 支持

This commit is contained in:
28810 2019-04-02 18:45:49 +08:00
parent 880c4dcdd1
commit 66cacaed88
6 changed files with 114 additions and 8 deletions

View File

@ -136,8 +136,20 @@ namespace FreeSql.Tests.MySql {
var dt2 = select.Limit(10).ToDataTable("id, 111222"); var dt2 = select.Limit(10).ToDataTable("id, 111222");
var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now });
} }
class TestDto {
public int id { get; set; }
public string name { get; set; }
}
[Fact] [Fact]
public void ToList() { public void ToList() {
var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title });
var testDto2 = select.Limit(10).ToList(a => new TestDto());
var testDto3 = select.Limit(10).ToList(a => new TestDto { });
var testDto4 = select.Limit(10).ToList(a => new TestDto() { });
var t0 = select.Limit(50).ToList(); var t0 = select.Limit(50).ToList();

View File

@ -128,8 +128,17 @@ namespace FreeSql.Tests.Oracle {
var dt2 = select.Limit(10).ToDataTable("id, 111222"); var dt2 = select.Limit(10).ToDataTable("id, 111222");
var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now });
} }
class TestDto {
public int id { get; set; }
public string name { get; set; }
}
[Fact] [Fact]
public void ToList() { public void ToList() {
var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title });
var testDto2 = select.Limit(10).ToList(a => new TestDto());
var testDto3 = select.Limit(10).ToList(a => new TestDto { });
var testDto4 = select.Limit(10).ToList(a => new TestDto() { });
} }
[Fact] [Fact]
public void ToOne() { public void ToOne() {

View File

@ -119,8 +119,19 @@ namespace FreeSql.Tests.PostgreSQL {
var dt2 = select.Limit(10).ToDataTable("id, 222"); var dt2 = select.Limit(10).ToDataTable("id, 222");
var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now });
} }
class TestDto {
public int id { get; set; }
public string name { get; set; }
}
[Fact] [Fact]
public void ToList() { public void ToList() {
var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title });
var testDto2 = select.Limit(10).ToList(a => new TestDto());
var testDto3 = select.Limit(10).ToList(a => new TestDto { });
var testDto4 = select.Limit(10).ToList(a => new TestDto() { });
var t1 = g.pgsql.Select<TestInfo>().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); var t1 = g.pgsql.Select<TestInfo>().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql();
var t2 = g.pgsql.Select<TestInfo>().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); var t2 = g.pgsql.Select<TestInfo>().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql();

View File

@ -130,8 +130,17 @@ namespace FreeSql.Tests.SqlServer {
var dt2 = select.Limit(10).ToDataTable("id, getdate()"); var dt2 = select.Limit(10).ToDataTable("id, getdate()");
var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now });
} }
class TestDto {
public int id { get; set; }
public string name { get; set; }
}
[Fact] [Fact]
public void ToList() { public void ToList() {
var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title });
var testDto2 = select.Limit(10).ToList(a => new TestDto());
var testDto3 = select.Limit(10).ToList(a => new TestDto { });
var testDto4 = select.Limit(10).ToList(a => new TestDto() { });
} }
[Fact] [Fact]
public void ToOne() { public void ToOne() {

View File

@ -122,8 +122,17 @@ namespace FreeSql.Tests.Sqlite {
var dt2 = select.Limit(10).ToDataTable("id, 111222"); var dt2 = select.Limit(10).ToDataTable("id, 111222");
var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now });
} }
class TestDto {
public int id { get; set; }
public string name { get; set; }
}
[Fact] [Fact]
public void ToList() { public void ToList() {
var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title });
var testDto2 = select.Limit(10).ToList(a => new TestDto());
var testDto3 = select.Limit(10).ToList(a => new TestDto { });
var testDto4 = select.Limit(10).ToList(a => new TestDto() { });
} }
[Fact] [Fact]
public void ToOne() { public void ToOne() {

View File

@ -17,6 +17,7 @@ namespace FreeSql.Internal {
_common = common; _common = common;
} }
static ConcurrentDictionary<Type, PropertyInfo[]> _dicReadAnonymousFieldDtoPropertys = new ConcurrentDictionary<Type, PropertyInfo[]>();
internal bool ReadAnonymousField(List<SelectTableInfo> _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Func<Expression[], string> getSelectGroupingMapString) { internal bool ReadAnonymousField(List<SelectTableInfo> _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
switch (exp.NodeType) { switch (exp.NodeType) {
case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString); case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString);
@ -78,17 +79,72 @@ namespace FreeSql.Internal {
return false; return false;
} }
return false; return false;
case ExpressionType.MemberInit:
var initExp = exp as MemberInitExpression;
parent.Consturctor = initExp.NewExpression.Type.GetConstructors()[0];
parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties;
if (initExp.Bindings?.Count > 0) {
//指定 dto映射
for (var a = 0; a < initExp.Bindings.Count; a++) {
var initAssignExp = (initExp.Bindings[a] as MemberAssignment);
if (initAssignExp == null) continue;
var child = new ReadAnonymousTypeInfo {
Property = initExp.Type.GetProperty(initExp.Bindings[a].Member.Name, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance),
CsName = initExp.Bindings[a].Member.Name,
CsType = initAssignExp.Expression.Type
};
parent.Childs.Add(child);
ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, getSelectGroupingMapString);
}
} else {
//dto 映射
var dtoProps = _dicReadAnonymousFieldDtoPropertys.GetOrAdd(initExp.NewExpression.Type, dtoType => dtoType.GetProperties());
var dtoTb0 = _tables.First();
foreach (var dtoProp in dtoProps) {
if (dtoTb0.Table.Columns.TryGetValue(dtoProp.Name, out var trydtocol)) {
var child = new ReadAnonymousTypeInfo {
Property = dtoProp,
CsName = dtoProp.Name,
CsType = dtoProp.PropertyType
};
parent.Childs.Add(child);
ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtoTb0.Parameter, dtoTb0.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString);
}
}
if (parent.Childs.Any() == false) throw new Exception($"映射异常:{initExp.NewExpression.Type.Name} 没有一个属性名和 {dtoTb0.Table.Type.Name} 相同");
}
return true;
case ExpressionType.New: case ExpressionType.New:
var newExp = exp as NewExpression; var newExp = exp as NewExpression;
parent.Consturctor = newExp.Type.GetConstructors()[0]; parent.Consturctor = newExp.Type.GetConstructors()[0];
parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Arguments; parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Arguments;
for (var a = 0; a < newExp.Members.Count; a++) { if (newExp.Members?.Count > 0) {
var child = new ReadAnonymousTypeInfo { for (var a = 0; a < newExp.Members.Count; a++) {
Property = newExp.Type.GetProperty(newExp.Members[a].Name, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance), var child = new ReadAnonymousTypeInfo {
CsName = newExp.Members[a].Name, CsType = newExp.Arguments[a].Type Property = newExp.Type.GetProperty(newExp.Members[a].Name, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance),
}; CsName = newExp.Members[a].Name,
parent.Childs.Add(child); CsType = newExp.Arguments[a].Type
ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], getSelectGroupingMapString); };
parent.Childs.Add(child);
ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], getSelectGroupingMapString);
}
} else {
//dto 映射
parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties;
var dtoProps = _dicReadAnonymousFieldDtoPropertys.GetOrAdd(newExp.Type, dtoType => dtoType.GetProperties());
var dtoTb0 = _tables.First();
foreach (var dtoProp in dtoProps) {
if (dtoTb0.Table.Columns.TryGetValue(dtoProp.Name, out var trydtocol)) {
var child = new ReadAnonymousTypeInfo {
Property = dtoProp,
CsName = dtoProp.Name,
CsType = dtoProp.PropertyType
};
parent.Childs.Add(child);
ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtoTb0.Parameter, dtoTb0.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString);
}
}
if (parent.Childs.Any() == false) throw new Exception($"映射异常:{newExp.Type.Name} 没有一个属性名和 {dtoTb0.Table.Type.Name} 相同");
} }
return true; return true;
} }
@ -121,7 +177,7 @@ namespace FreeSql.Internal {
var prop = parent.Childs[b].Property; var prop = parent.Childs[b].Property;
var objval = ReadAnonymous(parent.Childs[b], dr, ref index, notRead); var objval = ReadAnonymous(parent.Childs[b], dr, ref index, notRead);
var safeval = Utils.GetDataReaderValue(prop.PropertyType, objval); var safeval = Utils.GetDataReaderValue(prop.PropertyType, objval);
if (isnull == false && safeval == null && parent.Table.ColumnsByCs.TryGetValue(parent.Childs[b].CsName, out var trycol) && trycol.Attribute.IsPrimary) if (isnull == false && safeval == null && parent.Table != null && parent.Table.ColumnsByCs.TryGetValue(parent.Childs[b].CsName, out var trycol) && trycol.Attribute.IsPrimary)
isnull = true; isnull = true;
if (isnull == false) if (isnull == false)
prop.SetValue(ret, safeval, null); prop.SetValue(ret, safeval, null);