Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从数据库列动态创建C属性_C#_.net_Database_Properties - Fatal编程技术网

C# 从数据库列动态创建C属性

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属性实际上是存在的。它检查列,如果存在,则创建属性如果我理解正确,则您正在查找动态类型,该类型的属性直

我不知道这是否可以在C/.NET2.0中实现,但我希望能够向方法添加sql调用,并基于该调用构建属性。所以,它应该是这样的:

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的观点,简单的事情要简单。