Reflection 使用反射在运行时为dapper querymultiple Read方法动态创建类型

Reflection 使用反射在运行时为dapper querymultiple Read方法动态创建类型,reflection,types,dapper,Reflection,Types,Dapper,我试图在运行时动态传递类的类型。以下代码在代码部分给出错误: object newObject Activator.CreateInstance(Type.GetType(t.GetGenericArguments()[0].FullName)); data.Read<newObject>(); object newObject Activator.CreateInstance(Type.GetType(t.GetGenericArguments()[0].Full

我试图在运行时动态传递类的类型。以下代码在代码部分给出错误:

    object newObject Activator.CreateInstance(Type.GetType(t.GetGenericArguments()[0].FullName));
    data.Read<newObject>();
object newObject Activator.CreateInstance(Type.GetType(t.GetGenericArguments()[0].FullName));
data.Read();
我也试过了

    data.Read<Type.GetType(t.GetGenericArguments()[0].FullName)>();  
data.Read();
以下是完整的方法:

    public object FetchMultipleRecordSet(string storedProcedure, IList<QueryParameter> parameterCollection, object dataList)
    {
        if (!string.IsNullOrEmpty(storedProcedure))
        {
            using (SqlConnection sql = CreateDatabaseConnection())
            {
                DynamicParameters dynamicParameter = ConvertToDynamicParameters(parameterCollection);
                var data = sql.QueryMultiple(storedProcedure, dynamicParameter, null, null, commandType: CommandType.StoredProcedure);

                PropertyInfo[] properties = dataList.GetType().GetProperties();
                foreach (PropertyInfo property in properties)
                {
                    Type t = property.PropertyType;
                    if (t.BaseType == null && t.IsGenericType && t.Namespace == "System.Collection.Generic")
                    {
                        //property.SetValue(data.Read());
                        object newObject = Activator.CreateInstance(Type.GetType(t.GetGenericArguments()[0].FullName));
                        data.Read<>();    
                    }
                    else if (t.Namespace != "System")
                    {
                        //typeCollection.Add(Type.GetType(t.FullName));
                    }
                }
            }
        }

        return dataList;
    }
public object FetchMultipleRecordSet(字符串存储过程、IList参数集合、对象数据列表)
{
如果(!string.IsNullOrEmpty(StoredProcess))
{
使用(SqlConnection sql=CreateDatabaseConnection())
{
DynamicParameters dynamicParameter=ConvertToDynamicParameters(parameterCollection);
var data=sql.QueryMultiple(storedProcess,dynamicParameter,null,null,commandType:commandType.storedProcess);
PropertyInfo[]properties=dataList.GetType().GetProperties();
foreach(属性中的PropertyInfo属性)
{
类型t=property.PropertyType;
if(t.BaseType==null&&t.IsGenericType&&t.Namespace==“System.Collection.Generic”)
{
//property.SetValue(data.Read());
object newObject=Activator.CreateInstance(Type.GetType(t.GetGenericArguments()[0].FullName));
data.Read();
}
else if(t.Namespace!=“系统”)
{
//typeCollection.Add(Type.GetType(t.FullName));
}
}
}
}
返回数据列表;
}
以下是我要使用的视图模型:

    public class ResultCollection
    {
        public IList<ShortCodeList> ShortCodeListCollection { get; set; }
        public DateTime CurrentDate { get; set; }
        public UserMembershipPlan UserMembershipPlanRecord { get; set; }
        public IList<EmailRecipients> EmailRecipientsCollection { get; set; }
    }
公共类结果集合
{
公共IList ShortCodeListCollection{get;set;}
公共日期时间CurrentDate{get;set;}
公共UserMembershipPlan UserMembershipPlanRecord{get;set;}
公共IList EmailRecipientsCollection{get;set;}
}

我需要将类型传递到data.Read()中,以便泛型形式的属性可以与结果集进行映射。如果我传递“newObject”或“Type.GetType(t.GetGenericArguments()[0].FullName)”,它仍然会给我错误信息。这可能看起来很笨拙,但我认为它应该可以工作。

目前,dapper的类型化API使用泛型。有一个非类型化的API,但您需要自己进行成员映射。要通过类型调用泛型方法,需要在泛型方法上使用MethodInfo、MakeGenericMethod和Invoke。还有一种方法可以使用
动态
欺骗它,方法是在代码中添加一个shim方法,类似于:

dynamic template = ...  // activator etc
Evil(template, otherArgs...);

Evil<T>(T template, otherArgs...) {
    use some <T> method etc here
}
还有多网格阅读器:

public void TypeBasedViaTypeMulti()
{
    Type type = GetSomeType();

    dynamic first, second;
    using(var multi = connection.QueryMultiple(
        "select @A as [A], @B as [B]; select @C as [A], @D as [B]",
        new { A = 123, B = "abc", C = 456, D = "def" }))
    {
        first = multi.Read(type).Single();
        second = multi.Read(type).Single();
    }
    ((object)first).GetType().IsEqualTo(type);
    int a = first.A;
    string b = first.B;
    a.IsEqualTo(123);
    b.IsEqualTo("abc");

    ((object)second).GetType().IsEqualTo(type);
    a = second.A;
    b = second.B;
    a.IsEqualTo(456);
    b.IsEqualTo("def");
}

请注意,这些新API示例中的
动态
纯粹是为了测试方便<代码>动态
不是该方法的重要部分。

嗨,马克,谢谢你回答这个问题。我开始研究其他的概念。如果你能把你在这里添加的部分填给我,那就太好了。我几乎放弃了从这里得到任何答案的希望。@Deepak整个周末都在手机上-将在pc上添加一个例子
public void TypeBasedViaType()
{
    Type type = GetSomeType();

    dynamic actual = connection.Query(type,
        "select @A as [A], @B as [B]", new { A = 123, B = "abc" }
        ).FirstOrDefault();
    ((object)actual).GetType().IsEqualTo(type);
    int a = actual.A;
    string b = actual.B;
    a.IsEqualTo(123);
    b.IsEqualTo("abc");
}
public void TypeBasedViaTypeMulti()
{
    Type type = GetSomeType();

    dynamic first, second;
    using(var multi = connection.QueryMultiple(
        "select @A as [A], @B as [B]; select @C as [A], @D as [B]",
        new { A = 123, B = "abc", C = 456, D = "def" }))
    {
        first = multi.Read(type).Single();
        second = multi.Read(type).Single();
    }
    ((object)first).GetType().IsEqualTo(type);
    int a = first.A;
    string b = first.B;
    a.IsEqualTo(123);
    b.IsEqualTo("abc");

    ((object)second).GetType().IsEqualTo(type);
    a = second.A;
    b = second.B;
    a.IsEqualTo(456);
    b.IsEqualTo("def");
}