EF Динамический тип - SqlParameter уже содержится в другой SqlParameterCollection - PullRequest
0 голосов
/ 07 ноября 2018

У меня хранимая процедура выдаст динамический набор результатов

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

Предположим, я добавил динамические столбцы в Type Builder:

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 (новое 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 голосов
/ 07 ноября 2018

Звучит так, будто это произошло как результат отложенного выполнения . Обычно простой 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

Связанная проблема: Database.SqlQuery дает SqlParameter уже содержится в другой SqlParameterCollection

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...