EF动态类型-另一个SqlParameterCollection已包含SqlParameter

时间:2018-11-07 09:27:26

标签: c# entity-framework stored-procedures

我有一个存储过程将提供动态结果集

(Eg1. storedProcedureNameXX 4 - sql server result  may be 5 columns)
(Eg2. storedProcedureNameXX 1 - sql server result  may be 3 columns)

假设我已在类型生成器中添加了动态列:

TypeBuilder builder = CreateTypeBuilder("MyDynamicAssembly", "MyModule", "MyType")<br>

//Todo:get the dynamic column names

CreateAutoImplementedProperty(builder, "column1", typeof(string));
CreateAutoImplementedProperty(builder, "column2", typeof(string));
CreateAutoImplementedProperty(builder, "column3", typeof(string));

Type resultType = builder.CreateType();
var parameters = new List<SqlParameter>();
parameters.Add(new SqlParameter("parm1", 1));

var  **p1** = entity.Database
    .SqlQuery(resultType, "exec storedProcedureNameXX @parm1", parameters.ToArray());

P1变量错误:

  

“ SqlParameter已被另一个包含   SqlParameterCollection“无法放置ToList()

//使用了添加的方法
私有静态TypeBuilder createTypeBuilder(字符串assemblyName,字符串moduleName,字符串typeName)         {             TypeBuilder typeBuilder = AppDomain                 .CurrentDomain                 .DefineDynamicAssembly(new AssemblyName(assemblyName),                                        AssemblyBuilderAccess.Run)                 .DefineDynamicModule(moduleName)                 .DefineType(typeName,TypeAttributes.Public);             typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);             返回typeBuilder;         }
        私有静态无效createAutoImplementedProperty(             TypeBuilder构建器,字符串propertyName,类型propertyType)         {             const string PrivateFieldPrefix =“ m_”;             const string GetterPrefix =“ get_”;             const string SetterPrefix =“ set _”;

        // Generate the field.
        FieldBuilder fieldBuilder = builder.DefineField(
            string.Concat(PrivateFieldPrefix, propertyName),
                          propertyType, FieldAttributes.Private);

        // Generate the property
        PropertyBuilder propertyBuilder = builder.DefineProperty(
            propertyName, System.Reflection.PropertyAttributes.HasDefault, propertyType, null);

        // Property getter and setter attributes.
        MethodAttributes propertyMethodAttributes =
            MethodAttributes.Public | MethodAttributes.SpecialName |
            MethodAttributes.HideBySig;

        // Define the getter method.
        MethodBuilder getterMethod = builder.DefineMethod(
            string.Concat(GetterPrefix, propertyName),
            propertyMethodAttributes, propertyType, Type.EmptyTypes);

        // Emit the IL code.
        // ldarg.0
        // ldfld,_field
        // ret
        ILGenerator getterILCode = getterMethod.GetILGenerator();
        getterILCode.Emit(OpCodes.Ldarg_0);
        getterILCode.Emit(OpCodes.Ldfld, fieldBuilder);
        getterILCode.Emit(OpCodes.Ret);

        // Define the setter method.
        MethodBuilder setterMethod = builder.DefineMethod(
            string.Concat(SetterPrefix, propertyName),
            propertyMethodAttributes, null, new Type[] { propertyType });

        // Emit the IL code.
        // ldarg.0
        // ldarg.1
        // stfld,_field
        // ret
        ILGenerator setterILCode = setterMethod.GetILGenerator();
        setterILCode.Emit(OpCodes.Ldarg_0);
        setterILCode.Emit(OpCodes.Ldarg_1);
        setterILCode.Emit(OpCodes.Stfld, fieldBuilder);
        setterILCode.Emit(OpCodes.Ret);

        propertyBuilder.SetGetMethod(getterMethod);
        propertyBuilder.SetSetMethod(setterMethod);
    }    

1 个答案:

答案 0 :(得分:1)

类似的声音是由于deferred execution的影响而产生的。通常,简单的ToList()调用应该可以工作:

var p1 = entity.Database.SqlQuery(resultType, "exec storedProcedureNameXX @parm1", parameters.ToArray()).ToList();

如果如上所述的ToList()仍然无法正常工作,请尝试克隆现有的SqlParameter实例并像下面的示例一样使用它:

var p1 = entity.Database.SqlQuery(resultType, "exec storedProcedureNameXX @parm1", 
                parameters.Select(x => ((ICloneable)x).Clone()).ToArray()).ToList();

或使用Database.SqlQuery<T>

var p1 = entity.Database.SqlQuery<resultType>("exec storedProcedureNameXX @parm1", 
                    parameters.Select(x => ((ICloneable)x).Clone()).ToArray()).ToList();

参考:SqlParameter.ICloneable.Clone Method

相关问题:Database.SqlQuery gives the The SqlParameter is already contained by another SqlParameterCollection