FreeSql/FreeSql/Internal/Model/ColumnInfo.cs
28810 e9a8ad70a1 - 增加 ICodeFirst.IsGenerateCommandParameterWithLambda 选项,开启表达式解析的命令参数化;
- 增加 ExpressionCallContext 自定义函数上下文档 DbParameter 属性;
- 修复 IncludeMany(a => a.x1.x2.Childs) 当 x1, x2 为 null 的报 null 错误;
2019-11-22 21:55:36 +08:00

84 lines
4.0 KiB
C#

using FreeSql.DataAnnotations;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace FreeSql.Internal.Model
{
public class ColumnInfo
{
public TableInfo Table { get; set; }
public string CsName { get; set; }
public Type CsType { get; set; }
public ColumnAttribute Attribute { get; set; }
public string Comment { get; internal set; }
public string DbTypeText { get; internal set; }
public int DbSize { get; internal set; }
public byte DbPrecision { get; internal set; }
public byte DbScale { get; internal set; }
static ConcurrentDictionary<ColumnInfo, Func<object, object>> _dicGetMapValue = new ConcurrentDictionary<ColumnInfo, Func<object, object>>();
public object GetMapValue(object obj)
{
var func = _dicGetMapValue.GetOrAdd(this, col =>
{
var paramExp = Expression.Parameter(typeof(object));
var returnTarget = Expression.Label(typeof(object));
if (Attribute.MapType == CsType)
return Expression.Lambda<Func<object, object>>(
Expression.Block(
Expression.Return(returnTarget, Expression.Convert(
Expression.MakeMemberAccess(
Expression.TypeAs(paramExp, col.Table.Type),
Table.Properties[col.CsName]
), typeof(object))),
Expression.Label(returnTarget, Expression.Default(typeof(object)))
), new[] { paramExp }).Compile();
var retExp = Expression.Variable(typeof(object), "ret");
var blockExp = new List<Expression>();
blockExp.AddRange(new Expression[] {
Expression.Assign(retExp, Utils.GetDataReaderValueBlockExpression(Attribute.MapType,
Expression.MakeMemberAccess(
Expression.TypeAs(paramExp, col.Table.Type),
Table.Properties[col.CsName]
)
)),
Expression.Return(returnTarget, retExp),
Expression.Label(returnTarget, Expression.Default(typeof(object)))
});
return Expression.Lambda<Func<object, object>>(Expression.Block(new[] { retExp }, blockExp), new[] { paramExp }).Compile();
});
return func(obj);
}
static ConcurrentDictionary<ColumnInfo, Action<object, object>> _dicSetMapValue = new ConcurrentDictionary<ColumnInfo, Action<object, object>>();
public void SetMapValue(object obj, object val)
{
var func = _dicSetMapValue.GetOrAdd(this, col =>
{
var objExp = Expression.Parameter(typeof(object), "obj");
var valExp = Expression.Parameter(typeof(object), "val");
//if (Attribute.MapType == CsType)
// return Expression.Lambda<Action<object, object>>(
// Expression.Assign(Expression.MakeMemberAccess(
// Expression.TypeAs(objExp, col.Table.Type),
// Table.Properties[col.CsName]
// ), Expression.Convert(
// valExp,
// Attribute.MapType)), objExp, valExp).Compile();
return Expression.Lambda<Action<object, object>>(
Expression.Assign(Expression.MakeMemberAccess(
Expression.TypeAs(objExp, col.Table.Type),
Table.Properties[col.CsName]
), Expression.Convert(
Utils.GetDataReaderValueBlockExpression(CsType, valExp),
CsType)), objExp, valExp).Compile();
});
func(obj, val);
}
}
}