在C#中生成SQL的反射?

在C#中生成SQL的反射?,c#,mysql,orm,C#,Mysql,Orm,我有自己的ORM,但我注意到它的性能很差,例如当我得到100k的结果时。对于每个迭代,我都会反映每个类型、它的字段/属性以及它使用的类(1) 反映一个班级10万次变慢。有什么东西可以用来生成C代码,这样我就不需要使用反射了吗?我可以将重要的select查询重写为常规sql,而不是使用ORM,但我想先问问是否有工具 我使用的是mysql数据库 -编辑-临时解决方案。当我自己的orm创建表、插入和添加执行功能时,dapper.net似乎具有查询所需的性能。在这两者之间,我想我拥有我所需要的一切。(请

我有自己的ORM,但我注意到它的性能很差,例如当我得到100k的结果时。对于每个迭代,我都会反映每个类型、它的字段/属性以及它使用的类(1)

反映一个班级10万次变慢。有什么东西可以用来生成C代码,这样我就不需要使用反射了吗?我可以将重要的select查询重写为常规sql,而不是使用ORM,但我想先问问是否有工具

我使用的是mysql数据库


-编辑-临时解决方案。当我自己的orm创建表、插入和添加执行功能时,dapper.net似乎具有查询所需的性能。在这两者之间,我想我拥有我所需要的一切。(请记住,我需要dapper提供的选择性能,我不需要插入性能,除非我的站点变得巨大)

我自己,我会使用现有的ORM,但为了回答这个问题,下面是一个通过动态生成的setter设置属性的简单示例:

void Main()
{
    var setter = GetPropertySetter<MyClass>("MyProperty");

    var myClass = new MyClass();
    setter(myClass, "This was set by the setter");
    Console.WriteLine(myClass.MyProperty);
}

Action<T, object> GetPropertySetter<T>(string propertyName) 
{
    var property = typeof(T).GetProperty(propertyName);
    var target = Expression.Parameter(typeof(T));
    var value = Expression.Parameter(typeof(object));
    var assignment = Expression.Assign(Expression.MakeMemberAccess(target, property), Expression.Convert(value, property.PropertyType));
    var propertyGetterExpression = Expression.Lambda<Action<T, object>>(assignment, target, value);
    return propertyGetterExpression.Compile();
}

class MyClass {
    public string MyProperty { get; set; }
}
void Main()
{
var setter=GetPropertySetter(“MyProperty”);
var myClass=新的myClass();
setter(myClass,“这是由setter设置的”);
Console.WriteLine(myClass.MyProperty);
}
操作GetPropertySetter(字符串propertyName)
{
var property=typeof(T).GetProperty(propertyName);
var target=Expression.Parameter(typeof(T));
var值=表达式参数(typeof(object));
var assignment=Expression.Assign(Expression.MakeMemberAccess(target,property),Expression.Convert(value,property.PropertyType));
var propertyGetterExpression=Expression.Lambda(赋值、目标、值);
返回propertyGetterExpression.Compile();
}
类MyClass{
公共字符串MyProperty{get;set;}
}

(别忘了
使用System.Linq.Expressions;

我自己会使用现有的ORM,但为了回答这个问题,下面是一个通过动态生成的setter设置属性的简单示例:

void Main()
{
    var setter = GetPropertySetter<MyClass>("MyProperty");

    var myClass = new MyClass();
    setter(myClass, "This was set by the setter");
    Console.WriteLine(myClass.MyProperty);
}

Action<T, object> GetPropertySetter<T>(string propertyName) 
{
    var property = typeof(T).GetProperty(propertyName);
    var target = Expression.Parameter(typeof(T));
    var value = Expression.Parameter(typeof(object));
    var assignment = Expression.Assign(Expression.MakeMemberAccess(target, property), Expression.Convert(value, property.PropertyType));
    var propertyGetterExpression = Expression.Lambda<Action<T, object>>(assignment, target, value);
    return propertyGetterExpression.Compile();
}

class MyClass {
    public string MyProperty { get; set; }
}
void Main()
{
var setter=GetPropertySetter(“MyProperty”);
var myClass=新的myClass();
setter(myClass,“这是由setter设置的”);
Console.WriteLine(myClass.MyProperty);
}
操作GetPropertySetter(字符串propertyName)
{
var property=typeof(T).GetProperty(propertyName);
var target=Expression.Parameter(typeof(T));
var值=表达式参数(typeof(object));
var assignment=Expression.Assign(Expression.MakeMemberAccess(target,property),Expression.Convert(value,property.PropertyType));
var propertyGetterExpression=Expression.Lambda(赋值、目标、值);
返回propertyGetterExpression.Compile();
}
类MyClass{
公共字符串MyProperty{get;set;}
}


(别忘了
使用System.Linq.Expressions;

我想你可以使用缓存来为每种类型保留propertyInfo。

我想你可以使用缓存来为每种类型保留propertyInfo。

对于自动选择和生成+编译器CLR代码来说非常好,可以让它变得非常快

非常适合自动选择和生成+编译器CLR代码,使其变得非常快速

你可以为你所考虑的每种类型发射一个专门的类,使用<代码>系统.Nealth.EimIT < /Cord>命名空间。为什么你会麻烦编写自己的瑕疵(按你自己的推理)ORM,当有这么多的测试和测试可用?与其使用反射,不如尝试代码生成…@Mitch:这是大约2年前的事了,我在一周内写的。它完全符合我的需要(本地计算机,无性能要求,非常容易使用)。现在我需要一些不同的东西。@cdhowie:你是什么意思?问题是我反射了10万次,这并不是反射有多慢的事实。“这只是我想摆脱的开销。@米奇:有趣的是,实体框架看起来比我的ORM更难使用,如果它每个循环都反射,那么它也会有同样的问题。”。(ps):我的语法是代码> var > ls=CONN.SCOLLATION(“哪里!COL=(和!COL2=)”,A,B);< /COD> >我可以写<代码> FUNC(ls .FrestTo)(COL.DATA)。使用
System.Reflection.Emit
名称空间。既然有这么多经过尝试和测试的ORM可用,为什么还要费心编写自己的有缺陷(根据自己陈述的推理)ORM?与其使用反射,不如尝试代码生成…@Mitch:这是大约2年前的事了,我在一周内写的。它完全符合我的需要(本地计算机,无性能要求,非常容易使用)。现在我需要一些不同的东西。@cdhowie:你是什么意思?问题是我反射了10万次,这并不是反射有多慢的事实。“这只是我想摆脱的开销。@米奇:有趣的是,实体框架看起来比我的ORM更难使用,如果它每个循环都反射,那么它也会有同样的问题。”。(注:我的语法是
var ls=conn.SelectAll(“where!col=?AND!col2=?”,a,b);
我可以编写
func(ls.first().col.data)
。非常好,但在很大程度上不利于性能)好主意。请注意,这将为每个属性带来函数指针开销。如果OP希望对特定类的每个对象执行相同的操作序列,那么为每个类编译一个方法将更有效。(这不是对你的答案的批评,只是对可能阅读本文的人的另一个想法。)此外,应该指出,每个委托只应编译一次——之后,应该通过某种缓存机制重用以前编译的委托。为每次访问创建一个委托将比使用反射更昂贵。@cdhowie,这两个观点都很好,但最后一点特别需要提及。好主意。请注意,这将为每个属性带来函数指针开销。如果OP想要对pa的每个对象执行相同的操作序列