6

Я использую табличные значения функции с Entity Framework 5. Я только что получил эту ошибку:Entity Framework - Таблица функций - параметр уже существует

A parameter named 'EffectiveDate' already exists in the parameter collection. Parameter names must be unique in the parameter collection. Parameter name: parameter

Она была вызвана мне присоединиться вызовы таблицы -значные функции, принимающие один и тот же параметр.

Это ошибка/ограничение с помощью EF? Есть ли обходной путь? Сейчас я автоматически генерирую код (файл .edmx).

ответ

0

Не ошибка. Может быть, ограничение или упущение. По-видимому, этот прецедент никогда не принимался во внимание. EF может использовать автоматически созданные имена параметров, но, да, это просто не так.

Вам нужно прибегнуть к вызову одной из функций с помощью .AsEnumerable(). По какой-то причине это должна быть первая функция в соединении (как я уже говорил). Если вы вызываете вторую функцию с .AsEnumerable(), она все равно переводится на SQL, и столкновение имен все еще происходит.

9

Было бы очень приятно, если бы Microsoft сделала имена параметров уникальными, по крайней мере, на основе контекста.

Я создал проблему для этого here.

В то же время, я был в состоянии получить эту работу путем настройки нескольких функций в файле .Context.tt, так что это добавляет идентификатор GUID для каждого имени параметра во время выполнения:

private void WriteFunctionImport(TypeMapper typeMapper, CodeStringGenerator codeStringGenerator, EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) { 
    if (typeMapper.IsComposable(edmFunction)) 
    { 
#> 

    [EdmFunction("<#=edmFunction.NamespaceName#>", "<#=edmFunction.Name#>")] 
    <#=codeStringGenerator.ComposableFunctionMethod(edmFunction, modelNamespace)#> 
    {  var guid = Guid.NewGuid().ToString("N"); <#+ 
     codeStringGenerator.WriteFunctionParameters(edmFunction, " + guid", WriteFunctionParameter); 
#> 
     <#=codeStringGenerator.ComposableCreateQuery(edmFunction, modelNamespace)#> 
    } <#+ 
    } 
    else 
    { 
#> 

    <#=codeStringGenerator.FunctionMethod(edmFunction, modelNamespace, includeMergeOption)#> 
    { <#+ 
     codeStringGenerator.WriteFunctionParameters(edmFunction, "", WriteFunctionParameter); 
#> 
     <#=codeStringGenerator.ExecuteFunction(edmFunction, modelNamespace, includeMergeOption)#> 
    } <#+ 
     if (typeMapper.GenerateMergeOptionFunction(edmFunction, includeMergeOption)) 
     { 
      WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: true); 
     } 
    } } 

. ..

public void WriteFunctionParameters(EdmFunction edmFunction, string nameSuffix, Action<string, string, string, string> writeParameter) 
{ 
    var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); 
    foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable)) 
    { 
     var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null"; 
     var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\"" + nameSuffix + ", " + parameter.FunctionParameterName + ")"; 
     var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\"" + nameSuffix + ", typeof(" + parameter.RawClrTypeName + "))"; 
     writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit); 
    } 
} 

...

public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace) 
{ 
    var parameters = _typeMapper.GetParameters(edmFunction); 

    return string.Format(
     CultureInfo.InvariantCulture, 
     "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});", 
     _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), 
     edmFunction.NamespaceName, 
     edmFunction.Name, 
     string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName + "\" + guid + \"").ToArray()), 
     _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))); 
} 
Смежные вопросы