修复group by下的匿名和member init的绑定 发布x.6.0.35

This commit is contained in:
xuejiaming 2022-09-22 13:05:15 +08:00
parent a33de9395a
commit 269d1aa528
5 changed files with 86 additions and 11 deletions

View File

@ -15,6 +15,13 @@ namespace Sample.MySql.Controllers
public string Id { get; set; }
public int C { get; set; }
}
public class abc
{
public string id { get; set; }
public string name { get; set; }
public int count { get; set; }
}
[ApiController]
[Route("[controller]/[action]")]
public class WeatherForecastController : ControllerBase
@ -58,6 +65,24 @@ namespace Sample.MySql.Controllers
// Console.WriteLine("------------");
// using (var tran = _defaultTableDbContext.Database.BeginTransaction())
// {
var resultX1 = await _defaultTableDbContext.Set<SysUserMod>()
.Where(o => o.Id == "2" || o.Id == "3").GroupBy(o => new { o.Id,o.Name })
.Select(o => new
{
id = o.Key.Id,
name = o.Key.Name,
count = o.Count()
}).ToListAsync();
var resultX12 = await _defaultTableDbContext.Set<SysUserMod>()
.Where(o => o.Id == "2" || o.Id == "3").GroupBy(o => new { o.Id,o.Name })
.Select(o => new abc
{
id = o.Key.Id,
name = o.Key.Name,
count = o.Count()
}).ToListAsync();
var firstOrDefault = _defaultTableDbContext.Set<SysUserMod>().FromSqlRaw($"select * from {nameof(SysUserMod)}").FirstOrDefault();
var sysUserMods1 = _defaultTableDbContext.Set<SysTest>()

View File

@ -25,10 +25,6 @@ namespace ShardingCore.Extensions
throw new Exception($"type:{typeof(T)} not found [{name}] properity ");
}
var param_obj = Expression.Parameter(type);
var param_val = Expression.Parameter(typeof(object));
var body_obj = Expression.Convert(param_obj, type);
var body_val = Expression.Convert(param_val, p.PropertyType);
//获取设置属性的值的方法
var setMethod = p.GetSetMethod(true);
@ -36,6 +32,10 @@ namespace ShardingCore.Extensions
//如果只是只读,则setMethod==null
if (setMethod != null)
{
var param_obj = Expression.Parameter(type);
var param_val = Expression.Parameter(typeof(object));
var body_obj = Expression.Convert(param_obj, type);
var body_val = Expression.Convert(param_val, p.PropertyType);
var body = Expression.Call(param_obj, p.GetSetMethod(), body_val);
var setValue = Expression.Lambda<Action<T, object>>(body, param_obj, param_val).Compile();
setValue(t, value);

View File

@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
@ -87,5 +89,16 @@ namespace ShardingCore.Extensions
return Type.GetTypeCode(type) == TypeCode.Boolean;
}
public static bool IsAnonymousType(this Type type)
{
if (type == null)
throw new ArgumentNullException(nameof(type));
// HACK: The only way to detect anonymous types right now.
return Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute), false)
&& type.IsGenericType && type.Name.Contains("AnonymousType")
&& (type.Name.StartsWith("<>") || type.Name.StartsWith("VB$"))
&& type.Attributes.HasFlag(TypeAttributes.NotPublic);
}
}
}

View File

@ -25,14 +25,36 @@ namespace ShardingCore.Sharding.Enumerators.AggregateExtensions
var anonType = source.GetType();
var allProperties = anonType.GetProperties();
var allPropertyTypes= allProperties.Select(o=>o.PropertyType).ToArray();
var constantExpressions = allProperties.Select(o => Expression.Constant(o.GetValue(source))).ToArray();
if (anonType.IsAnonymousType())
{
var constantExpressions = allProperties.Select(o => Expression.Constant(o.GetValue(source))).ToArray();
var exp = Expression.New(
anonType.GetConstructor(allPropertyTypes),
constantExpressions);
var lambda = LambdaExpression.Lambda(exp);
TSource myObj = (TSource)lambda.Compile().DynamicInvoke();
return myObj;
}
else
{
var parameters = allProperties.Select(o => o.GetValue(source)).ToArray();
if (anonType.GetConstructors().Length == 1 &&
anonType.GetConstructors()[0].GetParameters().Length == allPropertyTypes.Length)
{
return (TSource)Activator.CreateInstance(anonType, parameters);
}
else
{
var instance = (TSource)Activator.CreateInstance(anonType);
foreach (var property in allProperties)
{
var value = property.GetValue(source);
instance.SetPropertyValue(property.Name,value);
}
var exp = Expression.New(
anonType.GetConstructor(allPropertyTypes),
constantExpressions);
var lambda = LambdaExpression.Lambda(exp);
TSource myObj = (TSource)lambda.Compile().DynamicInvoke();
return myObj;
return instance;
}
}
}
[ExcludeFromCodeCoverage]

View File

@ -125,6 +125,21 @@ namespace ShardingCore.Core.Internal.Visitors
var propertyInfo = declaringType.GetProperty(memberName);
_selectContext.SelectProperties.Add(new SelectOwnerProperty(declaringType, propertyInfo));
//memberExpression.Acc
}else if (expression is MemberInitExpression memberInitExpression)
{
foreach (var memberBinding in memberInitExpression.Bindings)
{
if (memberBinding is MemberAssignment memberAssignment)
{
if (memberAssignment.Expression is MemberExpression bindMemberExpression)
{
var declaringType = memberBinding.Member.DeclaringType;
var memberName = memberBinding.Member.Name;
var propertyInfo = declaringType.GetProperty(memberName);
_selectContext.SelectProperties.Add(new SelectOwnerProperty(declaringType, propertyInfo));
}
}
}
}
//if (expression != null)
//{