C# 从数据库列动态创建C属性
我不知道这是否可以在C/.NET2.0中实现,但我希望能够向方法添加sql调用,并基于该调用构建属性。所以,它应该是这样的:C# 从数据库列动态创建C属性,c#,.net,database,properties,C#,.net,Database,Properties,我不知道这是否可以在C/.NET2.0中实现,但我希望能够向方法添加sql调用,并基于该调用构建属性。所以,它应该是这样的: QueryResult result = QueryDataTable.Query("SELECT ...", "DataConnection"); int someVar = result.SomeTableId; 因此,在SELECT语句之前,SomeTableId属性实际上是存在的。它检查列,如果存在,则创建属性如果我理解正确,则您正在查找动态类型,该类型的属性直
QueryResult result = QueryDataTable.Query("SELECT ...", "DataConnection");
int someVar = result.SomeTableId;
因此,在SELECT语句之前,SomeTableId属性实际上是存在的。它检查列,如果存在,则创建属性如果我理解正确,则您正在查找动态类型,该类型的属性直到运行时才知道。据我所知,这些只有在dotnet4中才可能实现
select返回的列在生成时是未知的,这有什么原因吗?如果我理解正确,您正在寻找一个动态类型,该类型的属性在运行时才知道。据我所知,这些只有在dotnet4中才可能实现
是否有任何原因导致select返回的列在生成时未知?在.NET Framework 2.0中不可能。
您可以使用DataTable或KeyValuePairs来存储结果。在.NET Framework 2.0中不可能。
您可以使用DataTable或KeyValuePairs来存储结果。当然,可以在运行时创建一个类型,但它涉及一些相当神秘的黑魔法,我向您保证,这比您想做的要多 我相信,您的要求还有另一个解决方案 您计划如何处理已创建/修改的对象
也许另一种方法更合适。当然,在运行时创建一个类型是可能的,但它涉及一些相当神秘的黑魔法,我向你保证这比你想做的要多 我相信,您的要求还有另一个解决方案 您计划如何处理已创建/修改的对象
也许另一种方法更合适。在编译时,您如何知道在运行时之前未解决的问题?这是动态绑定,你不能这样做 如果可以修改任何内容,请在运行时使用reflection.emit键入,并在运行时使用reflection绑定到该方法 但你可能走错了路
我不知道这是否是因为在执行查询之前您不知道列,在这种情况下,您可能应该按照建议将结果存储在keyvaluepair中,否则您可以只映射到现有类型 在编译时,您如何知道在运行时之前未解决的问题?这是动态绑定,你不能这样做 如果可以修改任何内容,请在运行时使用reflection.emit键入,并在运行时使用reflection绑定到该方法 但你可能走错了路 我不知道这是否是因为在执行查询之前您不知道列,在这种情况下,您可能应该按照建议将结果存储在keyvaluepair中,否则您可以只映射到现有类型 可以通过Reflection.Emit名称空间 这是我以前编写的一段代码,它将DataTable列转换为类型,可能会有帮助:
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
static class DataTableExtensions
{
public static Type GetTableType(DataTable DTable)
{
// Create needed TypeBuilder helpers
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName("Anonymous");
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.Run);
ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(myAsmName.Name);
TypeBuilder myTypeBuilder = myModBuilder.DefineType(DTable.TableName, TypeAttributes.Public);
foreach (DataColumn col in DTable.Columns) {
var PropertyName = col.ColumnName;
var PropertyType = col.DataType;
FieldBuilder PropertyFieldBuilder = myTypeBuilder.DefineField("_" + PropertyName.ToLower, PropertyType, FieldAttributes.Private);
PropertyBuilder PBuilder = myTypeBuilder.DefineProperty(PropertyName, PropertyAttributes.HasDefault, col.DataType, null);
MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
MethodBuilder getPropertyBuilder = myTypeBuilder.DefineMethod("get" + PropertyName, getSetAttr, col.DataType, Type.EmptyTypes);
// Constructing IL Code for get and set Methods.
ILGenerator GetPropGenerator = getPropertyBuilder.GetILGenerator();
GetPropGenerator.Emit(OpCodes.Ldarg_0);
GetPropGenerator.Emit(OpCodes.Ldfld, PropertyFieldBuilder);
GetPropGenerator.Emit(OpCodes.Ret);
MethodBuilder setPropertyBuulder = myTypeBuilder.DefineMethod("set_" + PropertyName, getSetAttr, null, new Type[] { col.DataType });
ILGenerator SetPropGenerator = setPropertyBuulder.GetILGenerator();
SetPropGenerator.Emit(OpCodes.Ldarg_0);
SetPropGenerator.Emit(OpCodes.Ldarg_1);
SetPropGenerator.Emit(OpCodes.Stfld, PropertyFieldBuilder);
SetPropGenerator.Emit(OpCodes.Ret);
PBuilder.SetGetMethod(getPropertyBuilder);
PBuilder.SetSetMethod(setPropertyBuulder);
}
ConstructorInfo objCtor = typeof(object).GetConstructor(new Type[-1 + 1]);
ConstructorBuilder pointCtor = myTypeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);
ILGenerator ctorIL = pointCtor.GetILGenerator();
// Constructing IL Code for the Type Constructor.
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Call, objCtor);
ctorIL.Emit(OpCodes.Ret);
return myTypeBuilder.CreateType();
}
}
这可以通过Reflection.Emit命名空间实现
这是我以前编写的一段代码,它将DataTable列转换为类型,可能会有帮助:
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
static class DataTableExtensions
{
public static Type GetTableType(DataTable DTable)
{
// Create needed TypeBuilder helpers
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName("Anonymous");
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.Run);
ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(myAsmName.Name);
TypeBuilder myTypeBuilder = myModBuilder.DefineType(DTable.TableName, TypeAttributes.Public);
foreach (DataColumn col in DTable.Columns) {
var PropertyName = col.ColumnName;
var PropertyType = col.DataType;
FieldBuilder PropertyFieldBuilder = myTypeBuilder.DefineField("_" + PropertyName.ToLower, PropertyType, FieldAttributes.Private);
PropertyBuilder PBuilder = myTypeBuilder.DefineProperty(PropertyName, PropertyAttributes.HasDefault, col.DataType, null);
MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
MethodBuilder getPropertyBuilder = myTypeBuilder.DefineMethod("get" + PropertyName, getSetAttr, col.DataType, Type.EmptyTypes);
// Constructing IL Code for get and set Methods.
ILGenerator GetPropGenerator = getPropertyBuilder.GetILGenerator();
GetPropGenerator.Emit(OpCodes.Ldarg_0);
GetPropGenerator.Emit(OpCodes.Ldfld, PropertyFieldBuilder);
GetPropGenerator.Emit(OpCodes.Ret);
MethodBuilder setPropertyBuulder = myTypeBuilder.DefineMethod("set_" + PropertyName, getSetAttr, null, new Type[] { col.DataType });
ILGenerator SetPropGenerator = setPropertyBuulder.GetILGenerator();
SetPropGenerator.Emit(OpCodes.Ldarg_0);
SetPropGenerator.Emit(OpCodes.Ldarg_1);
SetPropGenerator.Emit(OpCodes.Stfld, PropertyFieldBuilder);
SetPropGenerator.Emit(OpCodes.Ret);
PBuilder.SetGetMethod(getPropertyBuilder);
PBuilder.SetSetMethod(setPropertyBuulder);
}
ConstructorInfo objCtor = typeof(object).GetConstructor(new Type[-1 + 1]);
ConstructorBuilder pointCtor = myTypeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);
ILGenerator ctorIL = pointCtor.GetILGenerator();
// Constructing IL Code for the Type Constructor.
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Call, objCtor);
ctorIL.Emit(OpCodes.Ret);
return myTypeBuilder.CreateType();
}
}
它可以是数据库中任何表的select语句。我看到了,但您将如何使用这些值?它可以是数据库中任何表的select语句。我看到了,但您将如何使用这些值?这在.NET 2.0中使用System.Reflection.Emit是完全可能的。在.NET 2.0中使用System.Reflection.emit是一个不错的示例,但这感觉有点像使用炸药点燃篝火。我同意Aaronaught的观点,让简单的事情变得简单。很好的例子,但这感觉有点像用炸药点燃篝火。我同意Aaronaught的观点,简单的事情要简单。