【问题标题】:Entity Framework - Table-Valued Functions - Parameter Already Exists实体框架 - 表值函数 - 参数已存在
【发布时间】:2013-10-14 08:29:26
【问题描述】:

我在 Entity Framework 5 中使用表值函数。我刚刚收到此错误:

参数集合中已存在名为“EffectiveDate”的参数。参数名称在参数集合中必须是唯一的。参数名称:参数

这是因为我加入了对采用相同参数的表值函数的调用。

这是 EF 的错误/限制吗?有解决方法吗?现在我正在自动生成代码(.edmx 文件)。

【问题讨论】:

    标签: entity-framework entity-framework-5 parameter-passing user-defined-functions


    【解决方案1】:

    不是错误。也许是限制或遗漏。显然,这个用例从未被考虑在内。 EF 可以使用自动创建的参数名称,但是,是的,它不能。

    您将不得不使用.AsEnumerable() 调用其中一个函数。出于某种原因,这必须是连接中的第一个函数(正如我所经历的那样)。如果您使用.AsEnumerable() 调用第二个函数,它仍然会被转换为 SQL,并且仍然会发生名称冲突。

    【讨论】:

      【解决方案2】:

      如果微软能让参数名称唯一,至少在每个上下文的基础上,那将是非常好的。

      我为此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())));
      }
      

      【讨论】:

        猜你喜欢
        • 2011-12-30
        • 2012-11-16
        • 2013-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多